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

Go to full version