4 ms·
> Can the optimiser really unroll the loop and only check the need_to_stop variable once!? Yes. The compiler can see that need_to_stop is not changed by any of
by nybble41 7y ago
> Can the optimiser really unroll the loop and only check the need_to_stop variable once!?
Yes. The compiler can see that need_to_stop is not changed by any of the code inside the loop, and since it wasn't qualified with "volatile" or using explicit atomic operations the compiler is free to assume that it won't be changed asynchronously. That makes need_to_stop a constant for the duration of the loop, so it should have the same effect (given those assumptions) whether the variable is checked once or before each call to do_something_quickly(). Checking once is considerably more efficient.
- nsajko 7y agoAre you sure atomics can help in this case? EDIT: also, volatile is a bad idea, too, unless you are doing something low-level like a kernel or hacking on memory mapped IO pins. It does not synchronize accesses between threads.
- plorkyeran 7y agoC11 atomics include a memory barrier, so making need_to_stop atomic would indeed suffice.
- nybble41 7y agoIn addition to what plorkyeran said: While volatile alone doesn't synchronize accesses between threads, it is enough to ensure that the variable is read separately in each iteration of the loop—though it might just be read from the L1 cache and not take into account writes from other cores.
- gwd 7y ago> the compiler is free to assume that it won't be changed asynchronously. This seems like it might possibly have been a reasonable assumption 30 years ago, when multi-processor machines were tens of thousands of dollars; but now that your watch has 4 cores, non-local variables changing should be considered the norm.
- jcranmer 7y agoThe modern language standards (C++11/C11 and newer) explicitly take multicore machines into account, and the memory model was specifically designed knowing the capabilities of hardware. The language standard says that the programmer is not permitted to write data races, even if they are benign. You either need to provide synchronization in the form of locks or explicit memory barriers, or you need to use special atomic variables whose semantics allow concurrent access without synchronization. Without these rules (or something substantially similar), compilers would instead be forced to add sequentially-consistent memory barriers around every memory access they couldn't prove was only within a single thread (i.e., add it to every single memory access). The resulting performance would be completely unacceptable.