public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Alignment of large structures in GCC
@ 2008-07-13 22:47 Alexey Neyman
  2008-07-14 19:15 ` Nicholas Miller
  2008-07-15 14:24 ` Andrew Haley
  0 siblings, 2 replies; 6+ messages in thread
From: Alexey Neyman @ 2008-07-13 22:47 UTC (permalink / raw)
  To: gcc-help

Hi,

I ran into the following problem using gcc: I am using some structures, 
which are put into a dedicated section. The linker concatenates these 
sections from all files; I have a linker script which assigns symbols 
to the start and end of this section. When I need to traverse all these 
structures, I then use the following loop:

  struct somename *p;
  for (p = &__start_section; p < &__end_section; p++) {
    ...

All worked well when the size of the structure was below 32 bytes. When 
I added an additional field, GCC suddenly started aligning each 
structure to 32 bytes - so the structures in this section are padded to 
32-byte boundary. As the size of the structure is 36 bytes, though, the 
loop above breaks on the 2nd element: it tries to access it at 
&__start_section + 36, while the structure is actually at 
&__start_section + 64.

I narrowed it down to the following example:

<<<
struct {
        int xxx[NINT];
} aaa __attribute__((section(".foo")));
<<<<

When compiled, GCC selects the following alignments:

$ gcc -o - -S gg.c -DNINT=7 | grep align
        .align 4
$ gcc -o - -S gg.c -DNINT=8 | grep align
        .align 32
$ gcc -o - -S gg.c -DNINT=9 | grep align
        .align 32

That's especially strange since __alignof__ reports the alignment of 
this structure as 4. It seems natural that the size of the structure 
should be a multiple of its alignment.

For now, I circumvented it by adding __attribute__((aligned(4))) to 
these structures. However, it may not be good if this structure gets a 
new member which would have a 8-byte alignment.

The question is, why does GCC perform such 32-byte alignment and is it 
possible to turn off such behavior globally?

P.S. GCC version:

$ gcc -v
Using built-in specs.
Target: i386-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-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.5.0-gcj-1.5.0.0/jre
--enable-libgcj-multifile --enable-java-maintainer-mode
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic
--host=i386-redhat-linux
Thread model: posix
gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)

Best regards,
Alexey.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: Alignment of large structures in GCC
  2008-07-13 22:47 Alignment of large structures in GCC Alexey Neyman
@ 2008-07-14 19:15 ` Nicholas Miller
  2008-07-15 14:24 ` Andrew Haley
  1 sibling, 0 replies; 6+ messages in thread
From: Nicholas Miller @ 2008-07-14 19:15 UTC (permalink / raw)
  To: gcc-help

Add the packed attribute "__attribute__ ((packed))" to where you are
instantiating these structures, if not the structures themselves. This
should override the aligning that is automatically done on it.

> -----Original Message-----
> From: gcc-help-owner@gcc.gnu.org [mailto:gcc-help-owner@gcc.gnu.org] On
> Behalf Of Alexey Neyman
> Sent: Sunday, July 13, 2008 2:28 PM
> To: gcc-help@gcc.gnu.org
> Subject: Alignment of large structures in GCC
> 
> Hi,
> 
> I ran into the following problem using gcc: I am using some structures,
> which are put into a dedicated section. The linker concatenates these
> sections from all files; I have a linker script which assigns symbols
> to the start and end of this section. When I need to traverse all these
> structures, I then use the following loop:
> 
>   struct somename *p;
>   for (p = &__start_section; p < &__end_section; p++) {
>     ...
> 
> All worked well when the size of the structure was below 32 bytes. When
> I added an additional field, GCC suddenly started aligning each
> structure to 32 bytes - so the structures in this section are padded to
> 32-byte boundary. As the size of the structure is 36 bytes, though, the
> loop above breaks on the 2nd element: it tries to access it at
> &__start_section + 36, while the structure is actually at
> &__start_section + 64.
> 
> I narrowed it down to the following example:
> 
> <<<
> struct {
>         int xxx[NINT];
> } aaa __attribute__((section(".foo")));
> <<<<
> 
> When compiled, GCC selects the following alignments:
> 
> $ gcc -o - -S gg.c -DNINT=7 | grep align
>         .align 4
> $ gcc -o - -S gg.c -DNINT=8 | grep align
>         .align 32
> $ gcc -o - -S gg.c -DNINT=9 | grep align
>         .align 32
> 
> That's especially strange since __alignof__ reports the alignment of
> this structure as 4. It seems natural that the size of the structure
> should be a multiple of its alignment.
> 
> For now, I circumvented it by adding __attribute__((aligned(4))) to
> these structures. However, it may not be good if this structure gets a
> new member which would have a 8-byte alignment.
> 
> The question is, why does GCC perform such 32-byte alignment and is it
> possible to turn off such behavior globally?
> 
> P.S. GCC version:
> 
> $ gcc -v
> Using built-in specs.
> Target: i386-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-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.5.0-gcj-1.5.0.0/jre
> --enable-libgcj-multifile --enable-java-maintainer-mode
> --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic
> --host=i386-redhat-linux
> Thread model: posix
> gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)
> 
> Best regards,
> Alexey.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Alignment of large structures in GCC
  2008-07-13 22:47 Alignment of large structures in GCC Alexey Neyman
  2008-07-14 19:15 ` Nicholas Miller
@ 2008-07-15 14:24 ` Andrew Haley
  2008-07-15 16:10   ` Alexey Neyman
  1 sibling, 1 reply; 6+ messages in thread
From: Andrew Haley @ 2008-07-15 14:24 UTC (permalink / raw)
  To: Alexey Neyman; +Cc: gcc-help

Alexey Neyman wrote:

> I ran into the following problem using gcc: I am using some structures, 
> which are put into a dedicated section. The linker concatenates these 
> sections from all files; I have a linker script which assigns symbols 
> to the start and end of this section. When I need to traverse all these 
> structures, I then use the following loop:
> 
>   struct somename *p;
>   for (p = &__start_section; p < &__end_section; p++) {
>     ...
> 
> All worked well when the size of the structure was below 32 bytes. When 
> I added an additional field, GCC suddenly started aligning each 
> structure to 32 bytes - so the structures in this section are padded to 
> 32-byte boundary. As the size of the structure is 36 bytes, though, the 
> loop above breaks on the 2nd element: it tries to access it at 
> &__start_section + 36, while the structure is actually at 
> &__start_section + 64.
> 
> I narrowed it down to the following example:
> 
> <<<
> struct {
>         int xxx[NINT];
> } aaa __attribute__((section(".foo")));
> <<<<

Please try making it a one-element array of that struct.  Does that
fix your problem?

> When compiled, GCC selects the following alignments:
> 
> $ gcc -o - -S gg.c -DNINT=7 | grep align
>         .align 4
> $ gcc -o - -S gg.c -DNINT=8 | grep align
>         .align 32
> $ gcc -o - -S gg.c -DNINT=9 | grep align
>         .align 32
> 
> That's especially strange since __alignof__ reports the alignment of 
> this structure as 4. It seems natural that the size of the structure 
> should be a multiple of its alignment.

Indeed.

> For now, I circumvented it by adding __attribute__((aligned(4))) to 
> these structures. However, it may not be good if this structure gets a 
> new member which would have a 8-byte alignment.
> 
> The question is, why does GCC perform such 32-byte alignment and is it 
> possible to turn off such behavior globally?

What target is this?  It might be an ABI requirement, or just an optimization.
Strictly speaking, gcc is allowed to do this.

Andrew.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Alignment of large structures in GCC
  2008-07-15 14:24 ` Andrew Haley
@ 2008-07-15 16:10   ` Alexey Neyman
  2008-07-15 21:17     ` Andrew Haley
  0 siblings, 1 reply; 6+ messages in thread
From: Alexey Neyman @ 2008-07-15 16:10 UTC (permalink / raw)
  To: Andrew Haley; +Cc: gcc-help

Andrew,

On 15 July 2008 Andrew Haley wrote:
> > I narrowed it down to the following example:
> >
> > <<<
> > struct {
> >         int xxx[NINT];
> > } aaa __attribute__((section(".foo")));
> > <<<<
>
> Please try making it a one-element array of that struct.  Does that
> fix your problem?

No, it doesn't.

struct {
        int xxx[NINT];
} aaa[1] __attribute__((section(".foo")));

$ gcc -o - -S gg.c -DNINT=9 | grep align
        .align 32

> > The question is, why does GCC perform such 32-byte alignment and is
> > it possible to turn off such behavior globally?
>
> What target is this?  It might be an ABI requirement, or just an
> optimization. Strictly speaking, gcc is allowed to do this.

$ gcc -dumpmachine
i386-redhat-linux

Best regards,
Alexey.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Alignment of large structures in GCC
  2008-07-15 16:10   ` Alexey Neyman
@ 2008-07-15 21:17     ` Andrew Haley
  0 siblings, 0 replies; 6+ messages in thread
From: Andrew Haley @ 2008-07-15 21:17 UTC (permalink / raw)
  To: Alexey Neyman; +Cc: gcc-help

Alexey Neyman wrote:
> Andrew,
> 
> On 15 July 2008 Andrew Haley wrote:
>>> I narrowed it down to the following example:
>>>
>>> <<<
>>> struct {
>>>         int xxx[NINT];
>>> } aaa __attribute__((section(".foo")));
>>> <<<<
>> Please try making it a one-element array of that struct.  Does that
>> fix your problem?
> 
> No, it doesn't.
> 
> struct {
>         int xxx[NINT];
> } aaa[1] __attribute__((section(".foo")));
> 
> $ gcc -o - -S gg.c -DNINT=9 | grep align
>         .align 32
> 
>>> The question is, why does GCC perform such 32-byte alignment and is
>>> it possible to turn off such behavior globally?
>> What target is this?  It might be an ABI requirement, or just an
>> optimization. Strictly speaking, gcc is allowed to do this.
> 
> $ gcc -dumpmachine
> i386-redhat-linux

I have no idea why this is happening; it may be a bug.  I'd have to
debug gcc to find the place that's doing the 32-aligning.  There may be
a simple answer, but I can't think of one.

Andrew.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: Alignment of large structures in GCC
@ 2008-07-15 11:10 Alexey Neyman
  0 siblings, 0 replies; 6+ messages in thread
From: Alexey Neyman @ 2008-07-15 11:10 UTC (permalink / raw)
  To: Nicholas Miller; +Cc: gcc-help

Nicholas,

Your suggestion is not good either. First of all, 'packed' attribute may 
also change the layout of the structure and may incur performance 
penalties even if the layout stays the same (e.g. on some machines it may 
make compiler generate the code which accesses the structure in bytes 
access to the structure instead of word/half-word access). I'd like to 
avoid that.

As I said, I worked it around by adding __attribute__((aligned(4))) 
instead. There is an even better solution: add 
__attribute__((aligned(__alignof__(struct foo)))) to the instances of the 
affected structures; this automatically selects the alignment as 
specified by command line options, structure contents, etc. 
E.g., -malign-double on i386 would cause the structure 
containing 'double' members to be aligned to 8 bytes.

However, the questions from original mail still stand:
* Why does GCC perform such alignments?
* Is it possible to turn such alignments off globally?

Regards,
Alexey.

> Add the packed attribute "__attribute__ ((packed))" to where you are
> instantiating these structures, if not the structures themselves. This
> should override the aligning that is automatically done on it.
>
>> -----Original Message-----
>> From: gcc-help-owner@gcc.gnu.org [mailto:gcc-help-owner@gcc.gnu.org] On
>> Behalf Of Alexey Neyman
>> Sent: Sunday, July 13, 2008 2:28 PM
>> To: gcc-help@gcc.gnu.org
>> Subject: Alignment of large structures in GCC
>> 
>> Hi,
>> 
>> I ran into the following problem using gcc: I am using some structures,
>> which are put into a dedicated section. The linker concatenates these
>> sections from all files; I have a linker script which assigns symbols
>> to the start and end of this section. When I need to traverse all these
>> structures, I then use the following loop:
>> 
>>   struct somename *p;
>>   for (p = &__start_section; p < &__end_section; p++) {
>>     ...
>> 
>> All worked well when the size of the structure was below 32 bytes. When
>> I added an additional field, GCC suddenly started aligning each
>> structure to 32 bytes - so the structures in this section are padded to
>> 32-byte boundary. As the size of the structure is 36 bytes, though, the
>> loop above breaks on the 2nd element: it tries to access it at
>> &__start_section + 36, while the structure is actually at
>> &__start_section + 64.
>> 
>> I narrowed it down to the following example:
>> 
>> <<<
>> struct {
>>         int xxx[NINT];
>> } aaa __attribute__((section(".foo")));
>> <<<<
>> 
>> When compiled, GCC selects the following alignments:
>> 
>> $ gcc -o - -S gg.c -DNINT=7 | grep align
>>         .align 4
>> $ gcc -o - -S gg.c -DNINT=8 | grep align
>>         .align 32
>> $ gcc -o - -S gg.c -DNINT=9 | grep align
>>         .align 32
>> 
>> That's especially strange since __alignof__ reports the alignment of
>> this structure as 4. It seems natural that the size of the structure
>> should be a multiple of its alignment.
>> 
>> For now, I circumvented it by adding __attribute__((aligned(4))) to
>> these structures. However, it may not be good if this structure gets a
>> new member which would have a 8-byte alignment.
>> 
>> The question is, why does GCC perform such 32-byte alignment and is it
>> possible to turn off such behavior globally?
>> 
>> P.S. GCC version:
>> 
>> $ gcc -v
>> Using built-in specs.
>> Target: i386-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-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.5.0-gcj-1.5.0.0/jre
>> --enable-libgcj-multifile --enable-java-maintainer-mode
>> --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic
>> --host=i386-redhat-linux
>> Thread model: posix
>> gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)
>> 
>> Best regards,
>> Alexey.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-07-15 16:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-07-13 22:47 Alignment of large structures in GCC Alexey Neyman
2008-07-14 19:15 ` Nicholas Miller
2008-07-15 14:24 ` Andrew Haley
2008-07-15 16:10   ` Alexey Neyman
2008-07-15 21:17     ` Andrew Haley
2008-07-15 11:10 Alexey Neyman

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).