public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* 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).