Paweł Batko via llvm-dev
2017-Nov-20 15:25 UTC
[llvm-dev] Meaning of loads/stores marked both atomic and volatile
Hi llvm-dev, I read about volatile and atomic modifiers in the docs[1], and I feel they make sense to me individually. However, I noticed that store[2] and load[3] instructions can be marked as both volatile and atomic. What's the use case for using both volatile and atomic on an instruction? Isn't it the case that atomic implies volatile? I guess it isn't, but I don't understand why. I'm guessing that while both volatile and atomic restrict reorderings, volatile prevents any kind of load or store elimination optimizations but atomic doesn't have such guarantee. E.g. I suspect that an atomic load, which can be implemented as a pair of a plain load and a fence instruction, can be optimized away to only a fence instruction. If it was both volatile and atomic, then such optimization would've been illegal. In other words, probably very imprecisely, volatile tells the compiler what it cannot do while atomic tells the cpu what it should do to guarantee certain memory model (and it'd also imply extra constraints on what a compiler can do). My other guess is that it's only to order 'atomic' instruction with 'volatile' instruction, thus the former becomes 'atomic volatile'. I'd appreciate links to any resources on the topic. [1] https://llvm.org/docs/LangRef.html#volatile-memory-accesses [2] https://llvm.org/docs/LangRef.html#store-instruction [3] https://llvm.org/docs/LangRef.html#i-load -- Paweł Batko
Tim Northover via llvm-dev
2017-Nov-20 15:41 UTC
[llvm-dev] Meaning of loads/stores marked both atomic and volatile
Hi Paweł, On 20 November 2017 at 15:25, Paweł Batko via llvm-dev <llvm-dev at lists.llvm.org> wrote:> What's the use case for using both volatile and atomic on an > instruction? Isn't it the case that atomic implies volatile?You pretty much got the semantics right straight after this. The compiler isn't allowed to add, remove or reorder volatile accesses but it is for some atomics if no other thread could prove it had. There are only a couple of valid uses for volatile these days (since everyone realised that using it for inter-thread synchronization was a bad idea); the main one is talking to memory-mapped hardware in an OS kernel or something. I could see someone using an atomic volatile there for something like talking to a DMA engine: write your buffer with normal instructions, then do a store-volatile-release to tell the DMA to start copying. I've not checked if that actually works for any architectures I know about though. Cheers. Tim.
Reid Kleckner via llvm-dev
2017-Nov-20 20:44 UTC
[llvm-dev] Meaning of loads/stores marked both atomic and volatile
I would say there are transforms that can be done on atomics that can't be done on volatile memory ops. For example, llvm should be able to mem2reg unescaped atomics because it knows they cannot be modified by other threads, but volatile operations will pin things in memory for use cases that are mostly outside the abstract model. On Mon, Nov 20, 2017, 7:26 AM Paweł Batko via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hi llvm-dev, > > I read about volatile and atomic modifiers in the docs[1], and I feel > they make sense to me individually. > However, I noticed that store[2] and load[3] instructions can be > marked as both volatile and atomic. > > What's the use case for using both volatile and atomic on an > instruction? Isn't it the case that atomic implies volatile? I guess > it isn't, but I don't understand why. > > I'm guessing that while both volatile and atomic restrict reorderings, > volatile prevents any kind of load or store elimination optimizations > but atomic doesn't have such guarantee. > E.g. I suspect that an atomic load, which can be implemented as a pair > of a plain load and a fence instruction, can be optimized away to only > a fence instruction. If it was both volatile and atomic, then such > optimization would've been illegal. > In other words, probably very imprecisely, volatile tells the compiler > what it cannot do while atomic tells the cpu what it should do to > guarantee certain memory model (and it'd also imply extra constraints > on what a compiler can do). > > My other guess is that it's only to order 'atomic' instruction with > 'volatile' instruction, thus the former becomes 'atomic volatile'. > > I'd appreciate links to any resources on the topic. > > > [1] https://llvm.org/docs/LangRef.html#volatile-memory-accesses > [2] https://llvm.org/docs/LangRef.html#store-instruction > [3] https://llvm.org/docs/LangRef.html#i-load > > -- > Paweł Batko > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171120/29974c41/attachment.html>
Paweł Batko via llvm-dev
2017-Nov-20 21:17 UTC
[llvm-dev] Meaning of loads/stores marked both atomic and volatile
Hi Tim, On 20 November 2017 at 16:41, Tim Northover <t.p.northover at gmail.com> wrote:> There are only a couple of valid uses for volatile these daysDo you mean volatile used alone or also the combination 'atomic volatile'? It think that 'atomic volatile' is very useful. Consider following pseudo-code examples, where all loads and stores are atomic (with some memory ordering constraints) but not volatile. Example 1. // shared variable int i = 0; // call this method from 10 threads void foo(){ int i = rand() % 2; int j = i; while(i == j){ printf("In the loop\n"); } } I claim that the loop can be optimized to an infinite loop by a compiler, because apparently j == i at all times in a single threaded program. If loads and stores (particularly the read in loop predicated) were also marked as volatile, it wouldn't have been possible. Is this correct? Example 2. // shared variable int i = 0; void signalHandler(){ i = 1; } void main(){ while(i == 0){ printf("In the loop\n"); } } Here I also claim that the loop can be optimized into an infinite loop if volatile is not used. Is this correct? -- Paweł Batko
Paweł Batko via llvm-dev
2017-Nov-20 21:22 UTC
[llvm-dev] Meaning of loads/stores marked both atomic and volatile
Hi Reid, On 20 November 2017 at 21:44, Reid Kleckner <rnk at google.com> wrote:> For example, llvm should be able to mem2reg > unescaped atomics because it knows they cannot be modified by other threads,Could you point to some resources that explain what an unescaped atomic is? -- Paweł Batko
Reasonably Related Threads
- Meaning of loads/stores marked both atomic and volatile
- [LLVMdev] GC in multithreaded (but with no shared state) environment
- [LLVMdev] Why can't atomic loads and stores handle floats?
- atomic ops are optimized with incorrect semantics .
- [LLVMdev] Inserting a synchronisation before volatile and atomic loads