From: Om on 29 Apr 2010 14:15 Hi, Do O1,2,3 optimizations affect the way volatile variables are handled in ifort 11.x ? For me the output of the following code is different for different optimization levels. Here I am putting a skeleton version. I am using volatile variables for controlling two threads (created using fortran-to-c interfaces) as follows : ================ common /counters/ i(2) volatile i i(2)=0 i(1)=0 ........ create threads do 55 while(i(2)==0) ! i(2) is set to 1 by other thread 55 continue ........ some computation ================ I am using volatile variables because otherwise program may not evaluate (i2==0) every time in the loop. However gfortran produces correct output every time. Any help would be highly appreciated !
From: steve on 29 Apr 2010 14:44 On Apr 29, 11:15 am, Om <helioph...(a)gmail.com> wrote: > Hi, > > Do O1,2,3 optimizations affect the way volatile variables are handled > in ifort 11.x ? For me the output of the following code is different > for different optimization levels. Here I am putting a skeleton > version. > > I am using volatile variables for controlling two threads (created > using fortran-to-c interfaces) as follows : > ================ > common /counters/ i(2) > volatile i > i(2)=0 > i(1)=0 > ....... create threads > do 55 while(i(2)==0) ! i(2) is set to 1 by other thread > 55 continue > ....... > some computation > ================ > I am using volatile variables because otherwise program may not > evaluate (i2==0) every time in the loop. > > However gfortran produces correct output every time. > > Any help would be highly appreciated ! Try removing the WHILE with DO 55 IF (.NOT. (i(2) == 0)) EXIT ! Equivalent to your WHILE .... 55 CONTINUE Looks like it might be a bug in Intel Fortran, but without a full self-contained test case, so can only guess. -- steve
From: JB on 29 Apr 2010 16:19 On 2010-04-29, Om <heliophile(a)gmail.com> wrote: > I am using volatile variables for controlling two threads (created > using fortran-to-c interfaces) as follows : >================ > common /counters/ i(2) > volatile i > i(2)=0 > i(1)=0 > ....... create threads > do 55 while(i(2)==0) ! i(2) is set to 1 by other thread > 55 continue > ....... > some computation >================ > I am using volatile variables because otherwise program may not > evaluate (i2==0) every time in the loop. Note that volatile in F2003 (and C99 and C++98 as well) does not guarantee the semantics needed for volatile variables to be used as synchronization primitives for mutual exclusion in the general case. Also note that the contrary view, while wrong, is depressingly common. For instance, consider the following slight modification of your code: ! i is shared among both threads common /counters/ i(2) volatile i integer :: priv ! Private variable in each thread i(2) = 0 i(1) = 0 ....... create threads ! Thread 1 |! Thread 2 | i(1) = 1 | i(2) = 1 | priv = i(2) | priv = i(1) | Now, simple intuition tells us that at this point the value of "priv" in both threads is either (1, 1), (0, 1) or (1, 0) depending on the order in which the threads were executed. However, real life isn't quite that simple, and on most architectures today, including x86(-64), a fourth option is possible, namely (0, 0). The solution is to use the concurrency primitives provided by the platform, which are (hopefully) made by people who understand the memory consistency model that the target hardware implements. On Linux or other POSIX platforms, this is provided as part of the pthreads library. Even so, there are (somewhat rare, but still) cases where the compiler might get things wrong. Luckily this situation is improving, due to the memory consistency model defined in C++0x and C1X, and at least the GCC optimizers are currently being audited for conformance. -- JB
From: Jim Xia on 29 Apr 2010 22:01 > > Do O1,2,3 optimizations affect the way volatile variables are handled > > in ifort 11.x ? For me the output of the following code is different > > for different optimization levels. Here I am putting a skeleton > > version. > > > I am using volatile variables for controlling two threads (created > > using fortran-to-c interfaces) as follows : > > ================ > > common /counters/ i(2) > > volatile i > > i(2)=0 > > i(1)=0 > > ....... create threads > > do 55 while(i(2)==0) ! i(2) is set to 1 by other thread > > 55 continue > > ....... > > some computation > > ================ > > I am using volatile variables because otherwise program may not > > evaluate (i2==0) every time in the loop. > > > However gfortran produces correct output every time. > > > Any help would be highly appreciated ! > > Try removing the WHILE with > > DO 55 > IF (.NOT. (i(2) == 0)) EXIT ! Equivalent to your WHILE > .... > 55 CONTINUE > > Looks like it might be a bug in Intel Fortran, but without a > full self-contained test case, so can only guess. My guess is this code change would work. However you may argue with compiler writer forever on whose fault it is for not having the original code working. The fact is Fortran volatile doesn't have the semantics you think it has. Not all members on the standard body ever agreed on the semantics of volatile variables. So if can, avoid using volatile altogether. For the code Om has shown, it's likely the "do while(i(2)==0)" has i(2) stuck with a register value and never got a chance to be flushed. Fortran never clearly says whether this is supposed to work or not. Cheers, Jim
From: Jim Xia on 29 Apr 2010 22:57 > It maybe never says "clearly" what volatile means, but it does say > > "NOTE 5.21 > The Fortran processor should use the most recent definition of a > volatile object when a value is required. Likewise, it should make the > most recent Fortran definition available...." A note is just a note. You should know better :-) > > and in normative text it says > > "The VOLATILE attribute specifies that an object may be referenced, > defined, or become undefined, by means not specified by the program." > Right. But what exactly does that sentence mean? > I thought everybody understood that the processor should do the right > thing and never keep a volatile variable in a register for "very > long." Common value preserving optimizations are basically forbidden > in a "good faith bug free" implementation of volatile. > I doubt. I didn't do a research on this, but I suspect there are many so-called "bugs" in C or C++ compilers on volatiles. Anyway, Om should argue with Intel compiler developers on this to see what they say. > If V is a volatile variable, then an expression like > V + 3.14 + V > should have 2 loads for V. What isn't specified is how many > fracto-seconds there are between the loads. That expression is completely different from "do while (i(2) == 0))". > > There's no way to specify in syntax or semantics what volatile > is supposed to do. The standard doesn't even require a processor > to have memory; it can't specify the timing of memory references. > But, what could the intent be other than to require the processor > to refresh the values whenever they are referenced? Yes and no. Can you tell me exactly how many times i(2) is referenced in "do while(i(2) == 0))"? > > I think it's like I/O. That also is loosely specified (a processor > doesn't have to do any and if it does it's all processor dependent; what > could be less specified?) Yet I/O works pretty prortably because > everybody understands it and wants it to work. > That's an interesting analogue I haven't though of. I'll think about it :-) Cheers, Jim
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: PGFIO-F-217, FORTRAN STOP Next: Reading lines in free format (*) with an occational string |