home *** CD-ROM | disk | FTP | other *** search
- From: Ronald Guilmette <rfg@ics.UCI.EDU>
-
- In article <5106@rtech.rtech.com> daveb@llama.UUCP writes:
- >Posix 1003.4 is the "real time" extension to Posix. It encompasses
- >shared memory and threads. By including these features it introduces
- >some new restrictions on the compilation environment, the gist of
- >which are that almost everything needs to be treated as "partially
- >volatile" (my phrase). The purpose of this note is to explore the
- >sense of the community tuned to ANSI C to see if this presents a
- >problem. I *don't* have any problems with the proposed Posix
- >restrictions, and in fact consider them essential. I do suspect that
- >some compiler writers may have some objections. Some of the tricks
- >now used by "hyper-optimizing" compilers would be illegal.
- >
- >The Draft 1003.4 Std. says in section 13.2:
- >
- > "The C translator must support at least the volatile key word.
-
- What the story here? ANSI C already requires this. Does 1003.4 not
- require ANSI C as a basis?
-
- > This is one mechanism that satisfies the reference to global
- > variables problems; however, it does not satisfy the code movement
- > around synchronization points problem.
-
- Is it just me or does this strike anyone else as being pure gibberish?
- Are these "problems" defined somewhere? Perhaps with examples of how
- these "problems" could crop up in some actual code?
-
- At the moment, I can only guess at what these "problems" are supposed to
- be. Based upon my best guess (given the *very* limited information
- available here) I'd have to say that these are one and the same problem,
- but that the people doing 1003.4 don't know that.
-
- This "code movement" problem is (I assume) just a question of being able to
- get the compiler *not* to move some code past some point. I believe that
- it is possible to do just that via proper use of the volatile keyword.
-
- Also, I believe that when the authors say "global variables" what they really
- mean here is "shared variables" (i.e. variables which may
- be accessed by two or more threads). Shared variables need not be "global"
- in the traditional C sense (i.e. "declared" variables which are declared
- outside of all functions). They could also be variables allocated via malloc()
- and possibly even local (auto) variables.
-
- Anyway, insuring the proper synchronization of accesses to shared variables
- (via proper use of "volatile") also restricts allowed compiler optimizations
- such as code motion.
-
- So as I say, I think these are really just one problem, but if somebody
- gave us some code examples, we would know for sure.
-
- > Additional facilities to
- > guarantee the validity of synchronization points must be supplied
- > (either in an implementation defined manner or in an ANSI C
- > defined manner)."
-
- Which synchronization points? All synchronization points? Some range of
- them? Individual synchronization points?
-
- >
- >It continues in the rationale:
- >
- > 13.3.1 "Standardization Issues"
- >
- > "Because IEEE Std 1003.4-199x is a source level standard and
- > because the majority of translators are designed without respect
- > to multiple streams of execution accessing global data, IEEE Std
- > 1003.4-199x must specify that translators provide some means for
- > the programmer to inform the translator that jointly accessed
- > variables are not cached in registers (at least at synchronization
-
- It's called "volatile" friends.
-
- > points). It drastically hurts the portability of IEEE Std
- > 1003.4-199x conforming applications that we can not specify a
- > mechanism that will work with all translators. Doing so is
- > outside the scope of IEEE Std 1003.4-199x. However, some
- > mechanism must be supplied or the {_POSIX_MEMORY_SHARING} and
- > {_POSIX_THREADS} options can not be used.
- >
- > . . .
- >
- > 13.3.1 "Rationale Relating to C language Requirements"
- >
- > "ANSI C does not define any base assumptions that the compiler
- > writer uses in choosing how the compiler will generate its code.
- > ANSI C states only that the compiler must generate code which
- > correctly executes an ANSI C-conforming programs. The potential of
- > a multi-threaded environment requires some base assumptions that
- > could conflict with the assumptions made by a compiler writer in
- > creating an ANSI C compiler but in no ways conflicts with the ANSI
- > C specification.
- >
- > "ANSI C does provide the keyword volatile; however, this can only
- > solve the memory coherence problem. It does not address the code
- > re-ordering problem.
-
- I'm appaled that the 1003.4 authors don't think that this "problem" is
- worthy of at least a coded example. If we had one, I'll bet that we
- could stick "volatile" in all the right places, and that this would
- solve the "problem".
-
- > ... further, using the volatile keyword to solve
- > memory coherence problems is both error prone and inefficient.
-
- Compared to what? Do the people writing this stuff come from marketing
- backgrounds?
-
- > It is error prone because every variable accessed by more than one
- > stream of execution must be marked volatile, and if the mark is
- > forgotten the program might exhibit nondeterministic behavior.
-
- Yes. If you write incorrect code, it will function incorrectly. Is this
- news to anyone?
-
- > The keyword causes inefficient code to be generated because any
- > reference or store into a volatile variable must be immediately
- > reflected in all other streams of execution, defeating any
- > optimization or caching.
-
- Dead wrong. Consider:
-
- int *p = malloc (sizeof (int));
- volatile int *vp = p;
-
- Now assume that two separate and independent threads diverge from this point
- onward. One of these two accesses the "heap" variable indirectly via the
- pointer "p". The other accesses the same variable via the pointer "vp".
- If the second thread stores indirectly through "vp" that store must be
- reflected immediately as having taken place at that point (a sequence
- point) for that thread only. The other thread (or threads) need not
- become aware of the store until they next reach one of their own sequence
- points (i.e. definitely not "immediately" as is claimed).
-
- So the judicious use of the volatile keyword need not necessarily lead to
- needless inefficiencies. Further, it is *not* true that optimizations
- must be "defeated". In the example I gave, optimizations (including
- code motion) could still be applied liberally within the second thread.
-
- The issue of the effect on caching efficiency of the use of "volatile" is
- potentially a real one, but *only* for multiprocessors (or uni-processors
- with write-back caches), and *only* when certain types of cache coherency
- schemes or certain types of cache coherency hardware is used on the
- multiprocessors in question. Even for such cases however, the effects
- will probably be small for any realistic programs on good hardware.
-
- > The volatile keyword is intended
- > primarily for communication with I/O devices, not for
- > communication between two streams of execution.
-
- Does it say that in the ANSI C standard somewhere? Does it say that in the
- ANSI C rationale? If not, then where does this idea come from?
-
- > "A much better method is to specify a set of requirements on the
- > translator and on the programmer minimum restrictions (it can
- > re-arrange and caches accesses_, but guarantee that data will be
- > consistent with respect to synchronization points. The memory
- > model provides a set of formal specifications that could be used
- > by a C translator. It is our recommendation that something
- > similar become part of the ANSI C definition."
- >
- >So, my question is, is the 1003.4 position controversial, or can I use
- >it to complain to compiler vendors?
-
- "Controversial" is not the adjective I had in mind.
-
- If these folks want to do language design, perhaps they should wait for the
- next revision of the ANSI C standard and see if anybody on the ANSI C
- committee will agree with these ? ideas.
-
- Volume-Number: Volume 19, Number 32
-
-