Ancient_Hacker said:
In the real world, you might be mildly interested to learn that
compilers usually place variables next to each other. Has on every
compiler I've ever tried, let's see: Unix v7 C on a 11/34, Borland C
since version 1.0, Microsoft C since 1985 IIRC, Sun C since 1985, SGI C
since 1997, gnu C since about forever. I'd love to hear of a single
counter-example.
Counter-examples from SGI C:
1) -ivpad Improves cache behavior by causing the linker to perform
intervariable padding of some large variables. This is in
effect by default. (C, C++, F77, F90)
2) -LD_LAYOUT:
multigot
This is for internal use. Usually, the linker attempts
to link everything, generating a single GOT. If this
fails, it reruns the layout phase and possibly creates
multiple GOT regions. This option causes the first
layout pass to fail. This is used in conjunction with
the mgot_threshold option described previously.
(GOT is Global Offset Table, and the relevance here is that when
procedure variables are large enough that they cannot all be completely
addressed by a single address register together with a standard-width
relative offset, then the linker will split the space to use multiple
address registers, in which case syntactically adjacent variables
will not necessarily be adjacent in addresses.)
3) -LD_LAYOUT:
reorder_file=feedback_file
Names a feedback file. When specified, function layout
in the text section is optimized to minimize page
faults and I-cache misses based upon the frequency
information in feedback_file. This file is usually
produced by prof(1)/cvperf(1) or sscord(1)/ssorder(1),
but a user can also construct or modify this ASCII
file.
4) initialized static or extern variables are not usually placed adjacent
to uninitialized static or extern variables, because the uninitialized
globals and statics are handled through a "demand-zero page" (a hardware
mechanism that automatically initializes a memory page to 0 when
it is allocated and given to a process.) Initialized variables have
to have their initial value read from the object file (which might
not happen until the first reference to the virtual memory page,
as SGI IRIX can postpone loading in code, constants, and
globals and statics, reading them from the object file when needed
[and for code and constants, instead of copying them to a disk swap file,
IRIX can just drop the virtual descriptor, leading the values to be
reloaded from the object file if they turn out to be needed later.]