* aligned attribute
@ 2006-12-20 13:28 Maurizio Vitale
2006-12-20 13:37 ` Andrew Haley
0 siblings, 1 reply; 8+ messages in thread
From: Maurizio Vitale @ 2006-12-20 13:28 UTC (permalink / raw)
To: gcc-help
I've a problem with understanding the behaviour of the aligned
attribute. Mike Stump already gave an answer on the developer list,
where I mistakenly posted my question yesterday, but I'm posting
here, providing additional details, in the hope to get a pointer to
where the semantics of the aligned attribute is documented.
I'm looking at C++ using gcc 4.1.1. Is there any difference between C
and C++ in the handling of the aligned attribute?
The OS is Linux Fedora Core 6 on an Intel Core 2 Duo (X86_64
architecture).
What I'm trying to achieve is a 16 byte alignment for all allocation
types. Mike suggested to use a special purpose allocator, but I do
need to cover more than dynamic allocation: some of the objects I
need to be aligned will be allocated by the user and global and
automatic allocation needs to be covered.
The reason I need the alignment is to carve out space for 4 tag bits.
The only architecture I'm interested is Linux on X86_64 (and later
Mac OS X on 64 bit Intels).
The compilers of interest are GCC 4.1.1 and, unfortunately for me,
gcc 3.4.5 and 3.2.3.
A small example shows that gcc tries to obey requests for 16 byte
alignments. With the following:
[mav@thor aloha]$ g++ -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
infodir=/usr/share/info --enable-shared --enable-threads=posix --
enable-checking=release --with-system-zlib --enable-__cxa_atexit --
disable-libunwind-exceptions --enable-libgcj-multifile --enable-
languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --
disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-
gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.1 20061011 (Red Hat 4.1.1-30)
And the following short program:
#include <iostream>
class C {
char c;
}; // __attribute__ ((aligned (16)));
C z;
char k;
C w;
int
main(int argc, char** argv) {
C c;
C d;
::std::cout << ::std::hex << "&c = 0x" << &c << "\n&d = 0x" << &d <<
"\n";
::std::cout << ::std::hex << "&z = 0x" << &z << "\n&w = 0x" << &w <<
"\n";
}
I get (compiled with g++ -o align align.cpp):
[ mav@thor aloha]$ ./align
&c = 0x0x7fff59d4149f
&d = 0x0x7fff59d4149e
&z = 0x0x601374
&w = 0x0x601376
If the aligned attribute is used, I get:
[mav@thor aloha]$ ./align
&c = 0x0x7fff92b26280
&d = 0x0x7fff92b26270
&z = 0x0x601380
&w = 0x0x6013a0
But when I move to my real application (an event-driven simulator) I
get stack allocated objects on 8-byte boundaries.
Now, my reading of the documentation is that the aligned attribute
(when used for types, as in the example I gave) applies to all
allocations (global, auto and heap). Is there any place where it is
said otherwise? Regardless of the documentation, what does the
implementation do?
The only caveat I've found is that the linker might be unable to obey
the alignment request. Here's the text from the doc:
Note that the effectiveness of aligned attributes may be limited by
inherent limitations in your linker. On many systems, the linker is
only able to arrange for
variables to be aligned up to a certain maximum alignment. (For some
linkers, the maximum supported alignment may be very very small.) If
your linker is
only able to align variables up to a maximum of 8 byte alignment,
then specifying aligned(16) in an __attribute__ will still only
provide you with 8 byte
alignment. See your linker documentation for further information.
The linker I'm using is GNU ld 2.17. The documentation contains no
machine-dependent section for X86_64 and I find no indication that a
16 byte alignment would not be allowed. That said, I have problems
understanding how the linker could even be in the picture for dynamic
and auto allocations.
In the first paragraph of the documentation for the aligned
attribute, it is said:
aligned (alignment)
This attribute specifies a minimum alignment (in bytes) for
variables of the specified type. For example, the declarations:
struct S { short f[3]; } __attribute__ ((aligned (8)));
typedef int more_aligned_int __attribute__ ((aligned
(8)));
force the compiler to insure (as far as it can) that each
variable whose type is struct S or more_aligned_int will be allocated
and aligned at least on a 8-byte boundary. On a SPARC, having all
variables of type struct S aligned to 8-byte boundaries allows the
compiler to use the ldd and std (doubleword load and
store) instructions when copying one variable of type struct S to
another, thus improving run-time efficiency.
Note that the alignment of any given struct or union type is
required by the ISO C standard to be at least a perfect multiple of
the lowest common multiple of the alignments of all of the members
of the struct or union in question. This means that you can
effectively adjust the alignment of a struct or union type by
attaching an aligned attribute to any one of the members of such a
type, but the notation illustrated in the example above is a more
obvious, intuitive, and
readable way to request the compiler to adjust the alignment of an
entire struct or union type.
This lead me to believe that every time a variable of type S is
allocated, the requested alignment is used (modulo linker limitations
of above). This paragraph is in the C section, so it doesn't,
strictly speaking, talk about C++ new style allocation, but (at least
in my mind) certainly covers automatic allocation on the stack.
And since there's no corresponding section in the C++ portion, I
assumed it was also the case for C++ style dynamic allocation.
Any input is greatly appreciated,
Thanks,
Maurizio
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: aligned attribute
2006-12-20 13:28 aligned attribute Maurizio Vitale
@ 2006-12-20 13:37 ` Andrew Haley
2006-12-20 13:52 ` Maurizio Vitale
2006-12-21 21:21 ` Tim Prince
0 siblings, 2 replies; 8+ messages in thread
From: Andrew Haley @ 2006-12-20 13:37 UTC (permalink / raw)
To: Maurizio Vitale; +Cc: gcc-help
Maurizio Vitale writes:
> But when I move to my real application (an event-driven simulator) I
> get stack allocated objects on 8-byte boundaries.
>
> Now, my reading of the documentation is that the aligned attribute
> (when used for types, as in the example I gave) applies to all
> allocations (global, auto and heap). Is there any place where it is
> said otherwise? Regardless of the documentation, what does the
> implementation do?
You can't get alignment any greater than the alignment of the stack
pointer. The alignment of the stack pointer is defined the the ABI of
the particular target you're using. I think it's 16 for x86
processors, but the processor itself doesn't enforce that: it varies
across operating systems and processor variants.
> This lead me to believe that every time a variable of type S is
> allocated, the requested alignment is used (modulo linker
> limitations of above).
Sure, but that only really applies to statically allocated objects. I
guess no-one appreciated that someone might want to use it for
auto variables.
Andrew.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: aligned attribute
2006-12-20 13:37 ` Andrew Haley
@ 2006-12-20 13:52 ` Maurizio Vitale
2006-12-21 21:23 ` Tim Prince
2006-12-21 21:21 ` Tim Prince
1 sibling, 1 reply; 8+ messages in thread
From: Maurizio Vitale @ 2006-12-20 13:52 UTC (permalink / raw)
To: gcc-help
Thanks. Now to add to my confusion, on my system __alignof(long
double) returns 16, which I presume means that all allocation,
static, dynamic and automatic for long double objects are 16 byte
aligned.
On Dec 20, 2006, at 8:37 AM, Andrew Haley wrote:
> Maurizio Vitale writes:
>> But when I move to my real application (an event-driven simulator) I
>> get stack allocated objects on 8-byte boundaries.
>>
>> Now, my reading of the documentation is that the aligned attribute
>> (when used for types, as in the example I gave) applies to all
>> allocations (global, auto and heap). Is there any place where it is
>> said otherwise? Regardless of the documentation, what does the
>> implementation do?
>
> You can't get alignment any greater than the alignment of the stack
> pointer. The alignment of the stack pointer is defined the the ABI of
> the particular target you're using. I think it's 16 for x86
> processors, but the processor itself doesn't enforce that: it varies
> across operating systems and processor variants.
>
>> This lead me to believe that every time a variable of type S is
>> allocated, the requested alignment is used (modulo linker
>> limitations of above).
>
> Sure, but that only really applies to statically allocated objects. I
> guess no-one appreciated that someone might want to use it for
> auto variables.
>
> Andrew.
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: aligned attribute
2006-12-20 13:37 ` Andrew Haley
2006-12-20 13:52 ` Maurizio Vitale
@ 2006-12-21 21:21 ` Tim Prince
1 sibling, 0 replies; 8+ messages in thread
From: Tim Prince @ 2006-12-21 21:21 UTC (permalink / raw)
To: Andrew Haley; +Cc: Maurizio Vitale, gcc-help
Andrew Haley wrote:
> Maurizio Vitale writes:
> > But when I move to my real application (an event-driven simulator) I
> > get stack allocated objects on 8-byte boundaries.
> >
> > Now, my reading of the documentation is that the aligned attribute
> > (when used for types, as in the example I gave) applies to all
> > allocations (global, auto and heap). Is there any place where it is
> > said otherwise? Regardless of the documentation, what does the
> > implementation do?
>
> You can't get alignment any greater than the alignment of the stack
> pointer. The alignment of the stack pointer is defined the the ABI of
> the particular target you're using. I think it's 16 for x86
> processors, but the processor itself doesn't enforce that: it varies
> across operating systems and processor variants.
It is also possible to build binutils with support for maximum alignment
less than 16. This was often done prior to widespread option of sse on
Opteron, for example. The compiler can't determine if the linker or OS
aren't supporting as large alignments as the compiler.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: aligned attribute
2006-12-20 13:52 ` Maurizio Vitale
@ 2006-12-21 21:23 ` Tim Prince
2006-12-21 21:31 ` Maurizio Vitale
0 siblings, 1 reply; 8+ messages in thread
From: Tim Prince @ 2006-12-21 21:23 UTC (permalink / raw)
To: Maurizio Vitale; +Cc: gcc-help
Maurizio Vitale wrote:
> Thanks. Now to add to my confusion, on my system __alignof(long double)
> returns 16, which I presume means that all allocation, static, dynamic
> and automatic for long double objects are 16 byte aligned.
>
This is a reasonable choice, that long doubles would be aligned for good
performance, unless the alignment is over-ridden by a packed or reduced
alignment specification.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: aligned attribute
2006-12-21 21:23 ` Tim Prince
@ 2006-12-21 21:31 ` Maurizio Vitale
2006-12-22 12:02 ` Andrew Haley
0 siblings, 1 reply; 8+ messages in thread
From: Maurizio Vitale @ 2006-12-21 21:31 UTC (permalink / raw)
To: tprince; +Cc: gcc-help
It is certainly reasonable, but if it is true it means that the
compiler is capable on linux, x86_64 to impose a 16 byte alignment on
some object for all type of allocations. Then I would expect an
__attribute__ ((aligned (16)) for a user defined type to be obeyed as
well.
I haven't tested whether long doubles are actually allocated on 16
byte boundaries in all case (global, auto and dynamic), mainly
because the tests would be inconclusive, unless you see an alignment
< 16.
I just mentioned the data point to see if it did say anything to GCC
developers.
On Dec 21, 2006, at 4:23 PM, Tim Prince wrote:
> Maurizio Vitale wrote:
>> Thanks. Now to add to my confusion, on my system __alignof(long
>> double) returns 16, which I presume means that all allocation,
>> static, dynamic and automatic for long double objects are 16 byte
>> aligned.
>
> This is a reasonable choice, that long doubles would be aligned for
> good performance, unless the alignment is over-ridden by a packed
> or reduced alignment specification.
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: aligned attribute
2006-12-21 21:31 ` Maurizio Vitale
@ 2006-12-22 12:02 ` Andrew Haley
2006-12-22 13:16 ` Maurizio Vitale
0 siblings, 1 reply; 8+ messages in thread
From: Andrew Haley @ 2006-12-22 12:02 UTC (permalink / raw)
To: Maurizio Vitale; +Cc: tprince, gcc-help
(top-posting fixed)
Maurizio Vitale writes:
>
> On Dec 21, 2006, at 4:23 PM, Tim Prince wrote:
>
> > Maurizio Vitale wrote:
> >> Thanks. Now to add to my confusion, on my system __alignof(long
> >> double) returns 16, which I presume means that all allocation,
> >> static, dynamic and automatic for long double objects are 16 byte
> >> aligned.
> >
> > This is a reasonable choice, that long doubles would be aligned for
> > good performance, unless the alignment is over-ridden by a packed
> > or reduced alignment specification.
>
> It is certainly reasonable, but if it is true it means that the
> compiler is capable on linux, x86_64 to impose a 16 byte alignment on
> some object for all type of allocations. Then I would expect an
> __attribute__ ((aligned (16)) for a user defined type to be obeyed as
> well.
>
> I haven't tested whether long doubles are actually allocated on 16
> byte boundaries in all case (global, auto and dynamic), mainly
> because the tests would be inconclusive, unless you see an alignment
> < 16.
>
> I just mentioned the data point to see if it did say anything to GCC
> developers.
Well, we don't know what question you're trying to ask. If you can be
specific, we'll give you an answer.
Andrew.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: aligned attribute
2006-12-22 12:02 ` Andrew Haley
@ 2006-12-22 13:16 ` Maurizio Vitale
0 siblings, 0 replies; 8+ messages in thread
From: Maurizio Vitale @ 2006-12-22 13:16 UTC (permalink / raw)
To: Andrew Haley; +Cc: gcc-help
The real question was in my other post within the same thread. I
summarize it here:
is struct S { } __attribute__ ((aligned (16))); supposed to give me
16 byte aligned allocation when object of type S are allocated:
1) globally
2) automatically on the stack
3) dynamically on the heap ?
The answers I got up to now are:
- maybe in 1) and 2) but depends on the stack alignment guarantees
of the ABI
- yes for 1) [modulo linker limitations]. Even though the
documentation doesn't says so the aligned attribute was only intended
for
global allocations.
- in general no, but depends on CPU/OS
I tend now to believe the right answer is the second one [and the
documentation should be fixed accordingly], but I haven't checked
the source code for GCC. Still, I've posted a small example in my
original post where GCC seems to obey the alignment for stack
allocated objects (and my larger example show GCC obeying the
alignemnt for heap allocated objects). But the example is really not
conclusive (there're also aligned global allocations that might
change the stack position).
My last post mentioned __alignof(long double) just to show that on
linux x86_64 GCC has the capability of enforcing 16 byte alignment
for global/heap/stack allocation (either that or __alignof would have
a very surprising semantics [btw, __alignof
(Struct_With_16_Byte_Aligned_Attribute) is 16 on my machine). This
should rule out the possibility of linker limitations or other
machine specific limitations preventing GCC from giving 16 bytes
alignments to objects and makes likely that the situation is either:
a) GCC only tries 1) [global allocation] and the documentation
should, imo, be clarified (both for the aligned attribute and the
behaviour of __alignof).
b) GCC tries 1), 2) and 3) and then I have at least one case in
which fails that I have to turn into a shorter example to submit as a
bug report
For the moment I haven't looked into the source code for GCC for
looking at what happens with the aligned attribute processing
Maurizio Vitale
On Dec 22, 2006, at 7:02 AM, Andrew Haley wrote:
> (top-posting fixed)
>
> Maurizio Vitale writes:
>>
>> On Dec 21, 2006, at 4:23 PM, Tim Prince wrote:
>>
>>> Maurizio Vitale wrote:
>>>> Thanks. Now to add to my confusion, on my system __alignof(long
>>>> double) returns 16, which I presume means that all allocation,
>>>> static, dynamic and automatic for long double objects are 16 byte
>>>> aligned.
>>>
>>> This is a reasonable choice, that long doubles would be aligned for
>>> good performance, unless the alignment is over-ridden by a packed
>>> or reduced alignment specification.
>>
>> It is certainly reasonable, but if it is true it means that the
>> compiler is capable on linux, x86_64 to impose a 16 byte alignment on
>> some object for all type of allocations. Then I would expect an
>> __attribute__ ((aligned (16)) for a user defined type to be obeyed as
>> well.
>>
>> I haven't tested whether long doubles are actually allocated on 16
>> byte boundaries in all case (global, auto and dynamic), mainly
>> because the tests would be inconclusive, unless you see an alignment
>> < 16.
>>
>> I just mentioned the data point to see if it did say anything to GCC
>> developers.
>
> Well, we don't know what question you're trying to ask. If you can be
> specific, we'll give you an answer.
>
> Andrew.
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2006-12-22 13:16 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-12-20 13:28 aligned attribute Maurizio Vitale
2006-12-20 13:37 ` Andrew Haley
2006-12-20 13:52 ` Maurizio Vitale
2006-12-21 21:23 ` Tim Prince
2006-12-21 21:31 ` Maurizio Vitale
2006-12-22 12:02 ` Andrew Haley
2006-12-22 13:16 ` Maurizio Vitale
2006-12-21 21:21 ` Tim Prince
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).