Forum > Windows
Aligning record fields for SSE
(1/1)
Marladu:
Porting over SSE code from delphi to freepascal I expected the rec_something.sse_data to be offset by 16byte from start of record:
type
rec_sse=record
sse1,sse2,sse3,sse4:single;
end;
{$align 16}{$packrecords 16}
type
rec_something=record
actual_data:longint;
sse_data:rec_sse;
end;
since in delphi the sse_data field would have an offset of 16 in the rec_something record, but it appears to work differently in free pascal as confirmed by http://bugs.freepascal.org/view.php?id=27480 so instead have to do something like:
type
rec_something=record
actual_data:longint;
padding_data1,padding_data2,padding_data3:longint;
sse_data:rec_sse;
end;
While this works I'm wondering if anyone has a cleaner solution to suggest (without reordering the sse_data field to be first in record) since this will be quite a bit harder to maintain.
marcov:
I don't understand why it should be expected to align to 16 bytes. The sse_data field has 4-byte as largest element, and thus aligns to 16-byte.
Maybe make it an union with a 128 bit set ? That's the only 128-bit type I can imagine.
--- Code: ---{$packrecords 16}
rec_somethingaligned=record
actual_data:longint;
case boolean of
false : ( sse_data:rec_sse);
true : ( xxx : set of 0..127);
end;
--- End code ---
Marladu:
I don't know how delphi sees things internally but with this following code in delphi the sse_data field will be offset by 16bytes from start of record rec_something, this is why I was expecting fpc to do it too:
type
rec_sse=record
sse1,sse2,sse3,sse4:single;
end;
{$align 16}
type
rec_something=record
actual_data:longint;
sse_data:rec_sse;
end;
Your idea about a 128bit set is pretty cool though I couldn't think of a 16byte type either.
edit: I tried your idea about using the union but it still gets offset by 4bytes in the record
Jonas Maebe:
The alignment of a record/array equals the alignment of its member with the highest alignment requirement (bar some ABI-specific exceptions). The i386 nor x86-64 ABIs specify that a record of 4 single/float elements should be aligned at a multiple 16 bytes, so this seems like a Delphi idiosyncrasy.
I don't think FPC currently supports a type that has an alignment of 16 on all supported platforms. However, we do have directive to change the minimum alignment of fields in record types: {$codealign recordmin=16}
Marladu:
Hi and thanks for the help Jonas, I was not aware of that variation of the $codealign compiler directive, and after testing it, it seems to neatly and cleanly solve my issue, thanks!!
Navigation
[0] Message Index