-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(deps): Upgrade to Rust 1.50.0 #6428
Changes from 7 commits
1dfeab0
80af0f7
cc6e799
40aec9e
ef2ebff
dbd61ae
8c383de
5a89924
680e199
300b565
653f30f
10665a9
43d1e5f
148332e
b993e30
de4eaee
f279014
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
1.49.0 | ||
1.50.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ impl SplitFn { | |
} | ||
|
||
impl Function for SplitFn { | ||
#[allow(clippy::collapsible_match)] // I expect this file to be going away shortly | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JeanMertz @FungusHumungus is this accurate? It seems like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, feel free to ignore this. I'll drop it once #6353 makes it into master (later today, as the CI is expected to be green within the hour). |
||
fn execute(&self, ctx: &Event) -> Result<QueryValue> { | ||
let string = { | ||
let bytes = required_value!(ctx, self.path, Value::Bytes(v) => v); | ||
|
@@ -71,10 +72,7 @@ impl Function for SplitFn { | |
}, | ||
Parameter { | ||
keyword: "pattern", | ||
accepts: |v| { | ||
matches!(v, QueryValue::Value(Value::Bytes(_)) | ||
| QueryValue::Regex(_)) | ||
}, | ||
accepts: |v| matches!(v, QueryValue::Value(Value::Bytes(_)) | QueryValue::Regex(_)), | ||
required: true, | ||
}, | ||
Parameter { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bruceg I'd appreciate your 👀 here.
compare_and_swap
was deprecated. I've swapped it for the equivalentcompare_exchange
call, but there is also acompare_exchange_weak
call that can purportedly generate more efficient assembly. The difference is:The nuance being that it might sometimes fail even if it could have succeeded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
compare_exchange_weak
will play much better on ARM and we should aim to use it.compare_exchange
emits instructions that require strong ordering of memory. A strong ordering means atomic operations are implicit acquire/release and probably Total Sorted Order (every CPU agrees about the order memory operations took place) where weak ordering allows CPUs to disagree, which is cool because some of them can shut off if need be or do other stuff. (ARM is weak, data-dependent which means every CPU eventually agrees on the results of operations andA->B
dereference is guaranteed thatA
is at least as fresh asB
. When systems don't support data-dependency things get bonkers.)For x86 with implicit strong order we'll never see additional fail loops, if we were an omniscient observer of the system. On ARM it's possible that we will because the CPU our instructions run on is lagging getting updates from other CPUs but it's an acceptable trade-off except in specialized circumstances.
I also suggest using ordering semantics
AcqRel
for success here, like you've done, andRelaxed
for failure. On ARM this'll mean more potential spins but overall more efficient results.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went ahead and made myself #6477 to tackle this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the detailed response! I think what you said makes sense and agree with the
AcqRel
for success andRelaxed
for failure. I'll leave that to your PR since this one maintains the current state.To deepen my understanding, under what circumstances would it be unacceptable?
I did note that the Rust PR for deprecating
compare_and_swap
only introduced onecompare_exchange_weak
:rust-lang/rust#79261
The PR comment seems to indicate that they were mostly just going for satisfying the deprecation rather than with an eye to improving performance though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. I'm good with that.
Solid question. Consider a situation where you execute some expensive function per loop, maybe it has a non-trivial side-effect or is expensive in CPU terms but you can't migrate it out of the loop. You might be better off paying the higher synchronization cost here, depending on what your goals are.
Quite right. Huh. Well, I was going off my own background understanding; ARM'll get better instructions emitted if we use
compare_exchange_weak
. If you take this programand generate x86 you'll see a
lock cmpxchg
instruction pair whether you usecompare_exchange_weak
orcompare_exchange
. On ARM when I compile forarm-unknown-linux-gnueabihf
at opt-level 3 the_weak
variant of the program clobbers less registers, has fewer exclusive loads and does less conditional work. I actually find opt-level 3 hard to read -- I think the compiler noticed all my values are powers of 2 and did clever things from that -- and fortunately when I call opt-level 0 it embeds the assembly ofcompare_exchange_weak
andcompare_exchange
. The strong version has more callee-save registers than I understand and calls further into helper functions that aren't inlined. The compiler source calls out to intrinsics, which makes sense, but without digging in further and brushing up on ARM -- which I need to do eventually -- I think the best I can offer is the strong variant emits more instructions to force coordination with the other CPUs. An ARM expert could pin point exactly where in the assembly for the above this happens, and if someone out there reading this knows I'd love to get taught. :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Yeah that makes sense as a trade-off. Thanks again for the thorough explanation!