Jeff Preshing

Jeff Preshing


220 comments posted · 1 followers · following 0

17 weeks ago @ Preshing on Programming - Memory Ordering at Com... · 0 replies · +1 points

Yes, if you make it a configuration option in your own project! Linux has its own configuration option for this: CONFIG_SMP. It's checked throughout the Linux source code to know whether it's compiling a kernel that will run on single processor system or multiple processor system.

22 weeks ago @ Preshing on Programming - Acquire and Release Fe... · 0 replies · +1 points

They compile to the same machine code on x86:

22 weeks ago @ Preshing on Programming - Acquire and Release Fe... · 0 replies · +1 points

I don't know. You could certainly devise an experiment to see if it makes any difference. But multicore x86 has been around for a long time, so I somehow doubt there are any wins to be found here.

23 weeks ago @ Preshing on Programming - Acquire and Release Se... · 0 replies · +1 points

Normally, the x86/64 doesn't reorder reads and doesn't reorder writes at the hardware level (among other things). That's why a compiler barrier is sufficient to implement those examples on x86/64. See Weak vs. Strong Memory Models.

32 weeks ago @ Preshing on Programming - The Synchronizes-With ... · 1 reply · +1 points

That's correct. TryReceiveMessage will eventually see ready=1. (In practice it happens in an extremely short time.)

32 weeks ago @ Preshing on Programming - Acquire and Release Se... · 0 replies · +1 points

I don't think your code will corrupt the data structure. Note that compare_exchange_weak() is a read-modify-write operation. It always "sees" the latest head. See ยง32.4.11 in the standard: "Atomic read-modify-write operations shall always read the last value (in the modification order) written before the write associated with the read-modify-write operation."

Acquire and release have nothing to do with that point! Acquire and release would only be used, in your example, to ensure that the contents of memory *pointed to* by head are made visible across threads, which is a different matter.

To complete your example (so that thread B actually inserts successfully), note that thread B should check the return value of compare_exchange_weak(), because the head may have been changed (by another thread) since the preceding load(). If the compare_exchange_week() failed, you just need to update new_node.ptr->next, then attempt the compare_exchange_weak() again (with a different "expected" argument). Repeat until it succeeds.

33 weeks ago @ Preshing on Programming - Hash Collision Probabi... · 0 replies · +1 points

Let's rephrase hash collision probabilities like this: "Given k randomly generated values, each selected (independently) from a set of N possible values, what is the probability that at least two of them are equal?" In this post, the set of possible values is the set of *all* integers from 0 to N - 1..... but the answer is the same for any set of size N.

In your case, if there are exactly 1000 possible values that can be chosen from, that mean N is 1000... not k. So that might be tripping you up -- a confusion between N and k. Also, make sure that scenario described here -- choosing k independent values, then checking if any of them are the same -- actually applies to your problem (I'm not sure if it does).

35 weeks ago @ Preshing on Programming - How to Build a CMake-B... · 0 replies · +1 points

The best practice is to always build your executable with debug information, even optimized executables intended for release. On Windows, the debug information is contained in a separate file (.pdb) and on Unix-like OSes, you can strip the debug information out of the executable using "strip". When it's time to release your software, release the stripped executable but keep a copy with debug information in your archives.

Debug information doesn't slow down the executable. It's just information. You can still build a fully optimized executable. When the executable is optimized, it's (much) harder to debug, but debug information still helps greatly, because it lets the debugger show you the callstack, global variables, and you can cast any address to a C/C++ type to inspect its contents.

This is common practice in the game industry and important for any application that relies on crash reporting, for example using Google Breakpad.

37 weeks ago @ Preshing on Programming - This Is Why They Call ... · 1 reply · +1 points

You're oversimplifying release semantics. Release semantics don't "make this modification visible to other threads". Release semantics ensure that once the modification becomes visible -- whenever that is! -- certain other modifications are visible as well. You might want to review Acquire and Release Semantics.

37 weeks ago @ Preshing on Programming - Double-Checked Locking... · 0 replies · +1 points

Yes, that's why memory_order_relaxed is not enough.