[Info-vax] Dave Cutler, Prism, DEC, Microsoft, etc.
John Reagan
johnrreagan at earthlink.net
Mon Nov 30 16:53:38 EST 2009
"JF Mezei" <jfmezei.spamnot at vaxination.ca> wrote in message
news:00cd4d03$0$6691$c3e8da3 at news.astraweb.com...
> The Compiler guy was heard typing:
>
>>> Remember that except for compiler bugs, alignment faults comes from the
>>> user
>>> lying to the compiler.
>
>
> Excuse me, but are there really circumstances where the programmer
> ("user" from Mr Reagan point of view) is lying to the compiler ?
>
> if I have a 100 byte record, and bytes 7 though 10 inclusively contain
> an integer, and I do:
>
> myint = (int *) &(buffer + 6) ; /* hopefully I have the syntax right*/
>
> In what way am I lying ? Does the compiler realise that this will be an
> unaligned access or will it be accusing me of lying ?
>
Pointers to ints by defintion point to ints. Ints are aligned on int-sized
boundaries. We'll assume that unless you tell us otherwise.
For this very simple case, you can argue the compiler can see that coming.
However, in more complicated pointer expressions where you share myint with
other routines, we can't tell.
>
> Out of curiosity, why do some CPUs have so much trouble fetching 4 bytes
> from an unaligned location ? Is it the CPU and CPU architecture that is
> the problem, or the RAM memory subsystem that can't fetch 4 bytes
> starting at an uneven memory address ?
Because those 4 bytes might cross a cache line boundary (yes the cache to
main memory interfaces often operate in 32-byte/64-byte/etc. chunks)? They
might cause multiple cache-to-main memory operations? They might cross a
page boundary where you don't have access to some of the bytes? Lots of
reasons.
>
>>> if you can't, tell the compiler
>>> what you did and we'll avoid the alignment fault.
>
> In C, how can I tell a compiler that trying to move 4 bytes into an
> integer variable MAY cause an alignment fault ? With variable record
> structures for instance, the location of an integer may vary and
> sometimes be un an uneven offset from start of buffer. But you won't
> know that at compile time since it would vary from record to record as
> you process a file for instance.
The Calling Standard says that records are aligned on the boundary of their
largest element (see #pragma nomember_align (base) syntax to tell
otherwise). We also know the compile-time offset from the start of the
record to the field. We then know to generate a single load instruction or
multiple smaller load instructions. Only when the record is found via a
pointer (or parameter) can it be sometimes unaligned. For local/global
variables, we allocate the record on the correct boundary.
I'm not sure what you mean by variable record structures? Like Pascal's
schema types with run-time sized and run-time offset fields? In that case,
we just generate the "may be byte aligned sequence" and use multiple smaller
loads (even if it happens to be aligned 99% of the time).
>
>
> BTW, does the X86-64 have similar performance handicap when trying to
> fetch an integer from unaligned memory location ?
The chip will fix it all up but it may involve multiple memory-operations.
I haven't studied that part in great detail.
John
More information about the Info-vax
mailing list