Optimal struct layout template?

Don nospam at nospam.com
Fri Dec 19 00:25:40 PST 2008


Sergey Gromov wrote:
> Thu, 18 Dec 2008 17:08:12 +0100, Don wrote:
> 
>>>>> On Thu, 18 Dec 2008 00:12:18 +0300, Sergey Gromov 
>>>>>> Tue, 16 Dec 2008 10:09:41 +0100, Don wrote:
>>>>>>> struct Foo { double, int } // 12 byte size, wants 8-byte alignment.
>>>>>> Foo.sizeof is 16.
>> Sergey is correct to the extent that in DMD, x.alignof <= x.sizeof for 
>> any x, and also x.sizeof is always an integer multiple of x.alignof.
>> When you assume that DMD is correct, then the simple ordering by 
>> .alignof indeed gives an optimal solution.
> 
> I think this is not something you can assume or not assume.  The set of
> conditions you mention is required and sufficient to respect alignment
> requirements of array elements while obeying the rules of pointer math.
> You cannot change them until you drop either pointer math or alignment
> guarantees.
> 
>> But these values *don't* reflect the machine behaviour.
>>
>> real.alignof is 2. But it's significantly faster (factor of 2) on most 
>> x86 machines to have real aligned to 16.
> 
> If you want size, you can use align():
> 
> struct ReallySmall
> {
>   int flags;
>   align(2) real value;
>   byte flags2;
>   align(2) real value2;
> }
> 
> Now ReallySmall.value.alignof == 2, and sorting will give you
> 
> struct ReallySmallSorted
> {
>   int flags;
>   align(2) real value;
>   align(2) real value2;
>   byte flags2;
> }
> 
> with ReallySmallSorted.sizeof == 28 and .alignof == 4 on Windows.
> 
>> These effects are not captured by the .alignof property for structs. To 
>> capture it in the Foo example, you'd need (for example) a 
>> Foo.memberalignof property, and a Foo.memberalignoffsetof property.
> 
> I don't understand this part.  Do you say that fields in different
> elements of the same array should be aligned differently?

No. It only applies in this situation where you have a struct which 
contains another struct which is align(1).

Given

align(1):
struct Foo {
   int a;
   double b;
}

(A)
struct Bar {
   int c;
   Foo d;
}

(B)
struct Bar {
   Foo d;
   int c;
}

(A) is better than (B) because it aligns Bar.d.b correctly. It's a 
trick, really -- it's using the other elements of Bar as padding for Foo.
I can't think of any other cases where this trick applies. As you say, 
an array of Foo[] cannot have all of its elements aligned.
So probably, the 'ideal solution' for the proposed template would be 
probe the insides of each struct to see if the trick can be used.

real80 is another case where the trick can be applied.

float[4] may also benefit from being aligned to a 16-byte boundary. With 
Intel's AVX instructions, something as large as float[16] might like to 
be on a 256-byte boundary, but all such cases are easy, since they 
involve x.sizeof == pow(2,k). align(1) structs and real80 are the only 
non-trivial ones.



More information about the Digitalmars-d mailing list