digitalmars.D - volatile
- Arcane Jill (29/29) Jun 26 2004 What is the intended purpose of the D keyword volatile?
- Walter (41/70) Jun 26 2004 "volatile" in C++ means a read or a write to a location cannot be "optim...
- Sean Kelly (5/13) Jun 26 2004 This is fantastic. So you're saying I don't have to write inline ASM to...
- Walter (8/21) Jun 26 2004 two
- =?ISO-8859-1?Q?Sigbj=F8rn_Lund_Olsen?= (14/46) Jun 26 2004 I wasn't aware of this, but I would tend to agree with Arcane Jill here,...
- Walter (19/30) Jun 26 2004 There is no consistency anyway between languages for the meaning of
- Ben Hinkle (3/8) Jun 27 2004 Can you add that part about "volatile flushes writes" to the doc? It jus...
- Walter (5/13) Jun 27 2004 caching
- Mike Swieton (29/38) Jun 26 2004 I asked this very question before ;) If I remember today I'll see about
- Walter (15/37) Jun 26 2004 volatile is
What is the intended purpose of the D keyword volatile? I understand that in a D statement such as: (which would be nonsense in C++, of course) there is merely a guarantee that all memory writes will be flushed before and after the statement. There is NOT a guarantee that the statement will be executed atomically. Forgive me, but ... I don't understand the point of this. Could someone explain? What's it FOR? On the other hand, the C++ use of volatile is horribly missing from D. In C++, a declaration such as: informs that compiler that agents unknown to the compiler will be reading and writing to this variable without warning. This affects the optimization which the compiler is allowed to perform. For instance, given the function: The compiler may NOT optimize away either the existence of the variable nor its initialization. Without the keyword volatile, the compiler could ditch x entirely. In D, it is (confusingly) possible to declare: However, this does NOT make x volatile in the C++ sense - it merely guarantees that all memory writes will be flushed before and after the variable x is initialized to zero. There may be a point to this, but I don't know what it is, and in any case the use of the keyword volatile for this strange purpose is most definitely counterintuitive if you're used to using the word in C++. Can anyone help me out here, or is it just a mad quirk? Arcane Jill
Jun 26 2004
"volatile" in C++ means a read or a write to a location cannot be "optimized away", and the value cannot be cached in a register, but the practical uses of that are nearly nil in modern optimizing compilers. If you need that kind of fine control over read/write cycles, you're coding for a very specific piece of hardware, and the inline assembler addresses that nicely. "volatile" in Java means that reads and writes to a variable are atomic. This can only be accomplished by wrapping the reads/writes in a synchronized block. D has synchronized blocks, so this capability is there. (On the x86 cpu's, atomic reads/writes happen anyway for 32 bit or less sized values. The ones that are not atomic are values bigger than 32 bits, like longs and doubles. How often do you need an atomic write of a double?) As optimizers have gotten better, and multi-CPU memory access along with write caching has become commonplace, the real problem emerged - that of guaranteeing that the *order* of reads and writes to some shared resource (like memory) can be specified. The C++ spec specifies order only in the presence of an assumed single threaded process, and operations can be reordered as long as they follow the "as if" rule, i.e. the end result is the same "as if" if were done in the same sequence as in the source. This all falls apart under aggressive optimization. (Scott Meyers presented a paper at SDWest giving some pretty damning evidence of this problem.) Neither C++ nor Java volatile semantics gives any help with this. The answer is to be able to figuratively draw a horizontal line between two statements in the code, and say all writes before that line are completed before the line is crossed, and all reads after that line do not happen until after all the writes are done. This is called a write barrier, and a read barrier. The D volatile statement is a way to specify where those barriers go in the code. The optimizer is prevented from moving reads and writes across that line, and to deal with memory caching problems in multi-cpu memory, any cpu instructions to 'flush' writes will be inserted. "Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cbjgmm$27ia$1 digitaldaemon.com...What is the intended purpose of the D keyword volatile? I understand that in a D statement such as: (which would be nonsense in C++, of course) there is merely a guaranteethat allmemory writes will be flushed before and after the statement. There is NOTaguarantee that the statement will be executed atomically. Forgive me, but... Idon't understand the point of this. Could someone explain? What's it FOR? On the other hand, the C++ use of volatile is horribly missing from D. InC++, adeclaration such as: informs that compiler that agents unknown to the compiler will be readingandwriting to this variable without warning. This affects the optimizationwhichthe compiler is allowed to perform. For instance, given the function: The compiler may NOT optimize away either the existence of the variablenor itsinitialization. Without the keyword volatile, the compiler could ditch x entirely. In D, it is (confusingly) possible to declare: However, this does NOT make x volatile in the C++ sense - it merelyguaranteesthat all memory writes will be flushed before and after the variable x is initialized to zero. There may be a point to this, but I don't know whatit is,and in any case the use of the keyword volatile for this strange purposeis mostdefinitely counterintuitive if you're used to using the word in C++. Can anyone help me out here, or is it just a mad quirk? Arcane Jill
Jun 26 2004
Walter wrote:The answer is to be able to figuratively draw a horizontal line between two statements in the code, and say all writes before that line are completed before the line is crossed, and all reads after that line do not happen until after all the writes are done. This is called a write barrier, and a read barrier. The D volatile statement is a way to specify where those barriers go in the code. The optimizer is prevented from moving reads and writes across that line, and to deal with memory caching problems in multi-cpu memory, any cpu instructions to 'flush' writes will be inserted.This is fantastic. So you're saying I don't have to write inline ASM to do (multi-cpu aware) atomic operations in D? This may be the best feature I've seen yet :) Sean
Jun 26 2004
"Sean Kelly" <sean f4.ca> wrote in message news:cbkhqp$i5u$1 digitaldaemon.com...Walter wrote:twoThe answer is to be able to figuratively draw a horizontal line betweencompletedstatements in the code, and say all writes before that line areabefore the line is crossed, and all reads after that line do not happen until after all the writes are done. This is called a write barrier, andandread barrier. The D volatile statement is a way to specify where those barriers go in the code. The optimizer is prevented from moving readsinserted.writes across that line, and to deal with memory caching problems in multi-cpu memory, any cpu instructions to 'flush' writes will beThis is fantastic. So you're saying I don't have to write inline ASM to do (multi-cpu aware) atomic operations in D? This may be the best feature I've seen yet :)You'll still have to if you want to use a LOCK prefix :-(
Jun 26 2004
Walter wrote:"volatile" in C++ means a read or a write to a location cannot be "optimized away", and the value cannot be cached in a register, but the practical uses of that are nearly nil in modern optimizing compilers. If you need that kind of fine control over read/write cycles, you're coding for a very specific piece of hardware, and the inline assembler addresses that nicely. "volatile" in Java means that reads and writes to a variable are atomic. This can only be accomplished by wrapping the reads/writes in a synchronized block. D has synchronized blocks, so this capability is there. (On the x86 cpu's, atomic reads/writes happen anyway for 32 bit or less sized values. The ones that are not atomic are values bigger than 32 bits, like longs and doubles. How often do you need an atomic write of a double?) As optimizers have gotten better, and multi-CPU memory access along with write caching has become commonplace, the real problem emerged - that of guaranteeing that the *order* of reads and writes to some shared resource (like memory) can be specified. The C++ spec specifies order only in the presence of an assumed single threaded process, and operations can be reordered as long as they follow the "as if" rule, i.e. the end result is the same "as if" if were done in the same sequence as in the source. This all falls apart under aggressive optimization. (Scott Meyers presented a paper at SDWest giving some pretty damning evidence of this problem.) Neither C++ nor Java volatile semantics gives any help with this. The answer is to be able to figuratively draw a horizontal line between two statements in the code, and say all writes before that line are completed before the line is crossed, and all reads after that line do not happen until after all the writes are done. This is called a write barrier, and a read barrier. The D volatile statement is a way to specify where those barriers go in the code. The optimizer is prevented from moving reads and writes across that line, and to deal with memory caching problems in multi-cpu memory, any cpu instructions to 'flush' writes will be inserted.I wasn't aware of this, but I would tend to agree with Arcane Jill here, that the use of 'volatile' in D doesn't make immediate sense. While I see what you're saying, I don't think the word 'volatile' semantically indicates an 'optimization barrier', and that possibly a different keyword would better indicate this, and diffuse confusion from coming from other languages. As to specific hardware, I think you're wrong. I've seen it used in timer code for the Allegro game programming library, and frankly it was exceptionally convenient. I wouldn't want to delve into inline assembler for the purpose it had there, and would never expect a highish level programming language to require me to. Cheers, Sigbjørn Lund Olsen
Jun 26 2004
"Sigbjørn Lund Olsen" <sigbjorn lundolsen.net> wrote in message news:cbkov1$sqt$1 digitaldaemon.com...I wasn't aware of this, but I would tend to agree with Arcane Jill here, that the use of 'volatile' in D doesn't make immediate sense. While I see what you're saying, I don't think the word 'volatile' semantically indicates an 'optimization barrier', and that possibly a different keyword would better indicate this, and diffuse confusion from coming from other languages.There is no consistency anyway between languages for the meaning of usage, and as I recall, Java will be moving that direction as well. All I can say is writing multithread safe code is very demanding, and one will have to read the documentation very carefully regardless.As to specific hardware, I think you're wrong. I've seen it used in timer code for the Allegro game programming library, and frankly it was exceptionally convenient. I wouldn't want to delve into inline assembler for the purpose it had there, and would never expect a highish level programming language to require me to.The C++ semantics don't even make much sense in a hardware environment with multilevel write caching. If you need to do a read cycle on a specific memory location, may I suggest: void read_cycle(void *location) { asm { mov EAX, location[ESP]; mov EAX,[EAX]; } } which does what you're asking for rather neatly, and an analogous one could be done for a write cycle. The volatile semantics in C++ ripple throughout everything, adding much complication it its wake, all to avoid having a single, simple function as above.
Jun 26 2004
The D volatile statement is a way to specify where those barriers go in the code. The optimizer is prevented from moving reads and writes across that line, and to deal with memory caching problems in multi-cpu memory, any cpu instructions to 'flush' writes will be inserted.Can you add that part about "volatile flushes writes" to the doc? It just mentions the code movement and doesn't say anything about caching. Also I assume volatile will force reads to be from main memory, right?
Jun 27 2004
"Ben Hinkle" <bhinkle4 juno.com> wrote in message news:cbmn17$cvn$1 digitaldaemon.com...cachingThe D volatile statement is a way to specify where those barriers go in the code. The optimizer is prevented from moving reads and writes across that line, and to deal with memorywillproblems in multi-cpu memory, any cpu instructions to 'flush' writesAcross a memory barrier, yes.be inserted.Can you add that part about "volatile flushes writes" to the doc? It just mentions the code movement and doesn't say anything about caching. Also I assume volatile will force reads to be from main memory, right?
Jun 27 2004
On Sat, 26 Jun 2004 09:47:02 +0000, Arcane Jill wrote:However, this does NOT make x volatile in the C++ sense - it merely guarantees that all memory writes will be flushed before and after the variable x is initialized to zero. There may be a point to this, but I don't know what it is, and in any case the use of the keyword volatile for this strange purpose is most definitely counterintuitive if you're used to using the word in C++. Can anyone help me out here, or is it just a mad quirk? Arcane JillI asked this very question before ;) If I remember today I'll see about wikiing it somewhere. In C++, if I say a variable is volatile, I do it as below, because volatile is a storage class in C++. volatile int x; x += 1; // this statement executed as volatile In D, I can't do that, because volatile is a statement modifier. You'd do something like this: int x; volatile { x += 1; } This allows you to access x in a volatile fashion only some of the time, allowing you to incur that overhead only where it's needed. If you want C++'s behavior, you might try something like this, using properties: int x() { volatile return _x; } int x(int i) { volatile return _x += i; } A real-world example where this is useful: In the concurrent library, there's a part where a worker thread reads a volatile flag to determine when to exit. However, the worker does not write to it. All writes to it happen under a lock, so I have it accessed volatily (that's a word now, dammit!) only in the worker thread. Of course, if you want to do that, you need to be *damn* careful. But then again, you'd be using Java if you wanted the language to baby-sit you. Mike Swieton __ Brutes find out where their talents lie; a bear will not attempt to fly. - Jonathan Swift
Jun 26 2004
"Mike Swieton" <mike swieton.net> wrote in message news:pan.2004.06.26.16.52.38.466542 swieton.net...In C++, if I say a variable is volatile, I do it as below, becausevolatile isa storage class in C++. volatile int x; x += 1; // this statement executed as volatile In D, I can't do that, because volatile is a statement modifier. You'd do something like this: int x; volatile { x += 1; } This allows you to access x in a volatile fashion only some of the time, allowing you to incur that overhead only where it's needed. If you wantC++'sbehavior, you might try something like this, using properties: int x() { volatile return _x; } int x(int i) { volatile return _x += i; }C++'s volatile doesn't prevent write caching in memory in multi-CPU systems, nor does it guarantee an order of reads/writes in multithreading. D's does.A real-world example where this is useful: In the concurrent library,there'sa part where a worker thread reads a volatile flag to determine when toexit.However, the worker does not write to it. All writes to it happen under a lock, so I have it accessed volatily (that's a word now, dammit!) only intheworker thread.If you think you have it working right, be sure and read "C++ and the Perils of Double-Checked Locking, Part I" (Scott Meyers, Andrei Alexandrescu), July 2004 Dr. Dobb's. Here's a taste of it: http://weblogs.asp.net/brada/archive/2004/05/12/130935.aspxOf course, if you want to do that, you need to be *damn* careful. But then again, you'd be using Java if you wanted the language to baby-sit you.Java's volatile won't help you, since it doesn't prevent reordering of operations.
Jun 26 2004