Live data from Hacker News

Ways to break your systems code using volatile (2010)

blog.regehr.org

11–20 of 77 posts

Re: Ways to break your systems code using volatile (2010)

#11
post #7

Edit: Looks like the slides had an inaccuracy (see replies). Huh, looks like I learned something today :) I think a good way of summarizing volatile is this slide from my parallel architectures class [1]: > Class exercise: describe everything that might occur during the > execution of this statement > volatile int x = 10 > > 1. Write to memory > > Now describe everything that might occur during the execution of > thi…

How does volatile bypass, for example, a TLB lookup or miss?

Re: Ways to break your systems code using volatile (2010)

#12

This should say 2010. I believe much of it is out of date, as C11 does have a memory model, and does provide both atomics and barriers. Many, if not most, uses of volatile should probably be replaced by atomics. https://en.cppreference.com/w/c/atomic

Herb Sutter's (three hour long!) Atomic Weapons talk goes over the modern meaning of volatile towards the end: https://youtu.be/KeLBd2EJLOU?t=5299

Re: Ways to break your systems code using volatile (2010)

#14
post #6

You really should just use volatile for device drivers when accessing IO space with side-effects. Do not use volatile to build your own synchronization primitives.

Don't forget about memory barriers. Otherwise your driver will fail on other CPU architectures. Just because it works on x86, doesn't mean it works on ARM, MIPS, POWER or RISC-V. CPUs other than x86 can reorder stores with other stores and loads with other loads. It can cause the CPU to do the store that starts DMA before the stores that set up length and address are done! Or just use C11 or C++11 memory model. Altho…

Even on x86, even with the C11 memory model, you can still get burned by transaction reordering as the MMIO passes through bridges. Plain old PCI can do this.

Re: Ways to break your systems code using volatile (2010)

#15

Ironically volatile is just as bad in Java for different reasons. Frequently used for "lock free" synchronization, its usually actually worse than using locks because it can't be cached between cores. The variable is always loaded from main memory, which is usually much worse than holding a lock mutex in registers.

> Frequently used for "lock free" synchronization, its usually actually worse than using locks

If you want lock-free what do you suggest we use instead of volatile?

> which is usually much worse than holding a lock mutex in registers

How can you hold a mutex in a register? That doesn't make any sense.

Re: Ways to break your systems code using volatile (2010)

#16
post #7

Edit: Looks like the slides had an inaccuracy (see replies). Huh, looks like I learned something today :) I think a good way of summarizing volatile is this slide from my parallel architectures class [1]: > Class exercise: describe everything that might occur during the > execution of this statement > volatile int x = 10 > > 1. Write to memory > > Now describe everything that might occur during the execution of > thi…

How does volatile bypass, for example, a TLB lookup or miss?

I didn't write the slides myself, but I think the implication is that the TLB is not consulted at all and the physical address is resolved again for every memory access. Of course, this is compiler / architecture / OS dependent though, so YMMV. The point is mostly to convey "lots of stuff you probably didn't consider is going on in the background and may have a nontrivial impact on parallelism."

Re: Ways to break your systems code using volatile (2010)

#17
post #16

Earlier quoted context omitted.

How does volatile bypass, for example, a TLB lookup or miss?

I didn't write the slides myself, but I think the implication is that the TLB is not consulted at all and the physical address is resolved again for every memory access. Of course, this is compiler / architecture / OS dependent though, so YMMV. The point is mostly to convey "lots of stuff you probably didn't consider is going on in the background and may have a nontrivial impact on parallelism."

> I think the implication is that the TLB is not consulted at all

This is not true.

Re: Ways to break your systems code using volatile (2010)

#18
post #13

Err...volatile just tells the compiler not to cache the value in a register, that's it. If you don't understand volatile you really, really are not the kind of programmer who should even think about using it.

The very first example in TFA shows the compiler doing more than this.

Re: Ways to break your systems code using volatile (2010)

#19
post #7

Edit: Looks like the slides had an inaccuracy (see replies). Huh, looks like I learned something today :) I think a good way of summarizing volatile is this slide from my parallel architectures class [1]: > Class exercise: describe everything that might occur during the > execution of this statement > volatile int x = 10 > > 1. Write to memory > > Now describe everything that might occur during the execution of > thi…

I don't understand these slides. The volatile keyword does not magically bypass the mechanism by which modern CPUs write to main memory. Am I missing something, or are they somehow meant to be ironic?

It (in theory) should bypass any caches in between physical memory and the CPU. Of course this is compiler/arch/OS dependent so YMMV...

The slide is admittedly a bit vague, the point is mostly to convey "lots of complicated things that you probably haven't considered are going on in the background to speed up memory accesses in a uniprocessor model." Keep in mind the class is exploring parallel architectures, and that lecture is about snooping-based cache coherence.

Re: Ways to break your systems code using volatile (2010)

#20
post #16

Earlier quoted context omitted.

I didn't write the slides myself, but I think the implication is that the TLB is not consulted at all and the physical address is resolved again for every memory access. Of course, this is compiler / architecture / OS dependent though, so YMMV. The point is mostly to convey "lots of stuff you probably didn't consider is going on in the background and may have a nontrivial impact on parallelism."

> I think the implication is that the TLB is not consulted at all This is not true.

Could you clarify? I am merely a student of that class and we didn't discuss TLBs in detail so I'm all ears for details.
Post reply on HN