[Info-vax] yet another sys$qiow question

John Reagan xyzzy1959 at gmail.com
Sat Aug 22 08:57:18 EDT 2015


On Saturday, August 22, 2015 at 12:29:06 AM UTC-4, JF Mezei wrote:
> I think I understand the volatile issue.
> 
> However, since the IOSB is a structure, pedandically speaking, wouldn't
> the compiler treat each member of the structure independantly ?
> 
> aka: reading the first member repeatedly might cause it to be optimized
> to register (or optimized away), but even if it has happened, reading
> the second member of structure would cause a memory fetch of the second
> value.   Right ?
> 

Depends if the structure's address has been taken.  That would keep it out of any registers.  GEM attempts to merge nearby structure references to reduce the total number of fetches/stores and to eliminate smaller references (remember that the first Alpha chips only had 32 and 64 bit memory operations - byte and word came later).  It is also influenced by the /GRANULARITY qualifier (which has little use on modern Alpha or on Itanium).

Some language definitions don't even require that the fields be laid out in the same lexical order or even allocated at all.  The Pascal standard would let us reshuffle RECORDs and eliminate unused fields.  However, that doesn't fit well in the VMS multi-language environment.  The Calling Standard prescribes some structure allocation and alignment rules above-and-beyond those required by language standards.

> 
> What about character buffers ?
> 
> Say I put 0x00 as first byte of a 250 byte char buffer. Call QIO to read
> data into buffer, and then loop until the first byte of buffer is no
> longer 0 (I know, even worse practice than looing to check IOSB :-)
> 
> 
> Would the compiler also optimize this loop away, even if it is character
> data ?

If the buffer was passed as an argument to $QIO, then we might fetch the byte once and use the cached value.  The compiler would think the data would be in place immediately after to call to $QIO.  You wouldn't have this problem with $QIOW.  The compiler doesn't know "character" from "bytes".

> 
> From a programmer's point of view, if I were to test for
> strlen(buffer) != 0
> 
> How do I know as a programmer whether "strlen" will be considered an
> external routine (which will impart "volatile" on buffer), 

Routines don't "impart" anything.  They don't magically turn non-volatile variables into volatile variables.  They ARE considered possible assignments. External routines are just considered to update all global variables, write into all of the heap, update all their 'by-reference' parameters, etc.

> routine which the compiler will inline code, and then optimize because
> it knows that strlen won't modify buffer so the whole thing can be
> optimized away ?

C compilers generally know which "builtin" routines don't have side-effects.  We know that "strlen" won't change the buffer.

I doubt an average code-generator would optimize that test away in the general case.  It would have to deal with array analysis and track values at the element level.  I suppose if you wrote code like:

if (buffer[0] == '\0') len = strlen(buffer);

then a compile could do that optimization.  However, that code would be rare and real code isn't so easy to analyze.  I personally wouldn't make the compiler spend time to look for stupid code sequences.  

> 
> If I declare buffr as "volatile", it is correct to state that I no
> longer have to worry about whether a routine is external or inline code
> since buffer will always be assumed it could change ?

Why worry?  If you pass a non-volatile buffer to some synchronous routine (external or internal), the language definition and the compiler know what is going on.  Ignoring threading for a moment, the compiler knows that a variable may change values only at certain points (increment, decrement, assignment, passed as parameter, etc.)  It is only the case where a variable may change at OTHER points is when you want volatile.




More information about the Info-vax mailing list