Recent

Author Topic: Aligning record fields for SSE  (Read 6048 times)

Marladu

  • New Member
  • *
  • Posts: 19
Aligning record fields for SSE
« on: February 16, 2015, 08:19:00 pm »
 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

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: Aligning record fields for SSE
« Reply #1 on: February 16, 2015, 09:46:22 pm »
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: [Select]
{$packrecords 16}
 rec_somethingaligned=record
  actual_data:longint;
  case boolean of
    false : (  sse_data:rec_sse);
    true  : ( xxx : set of 0..127);
 end;

Marladu

  • New Member
  • *
  • Posts: 19
Re: Aligning record fields for SSE
« Reply #2 on: February 16, 2015, 11:16:04 pm »
 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
« Last Edit: February 16, 2015, 11:37:57 pm by Marladu »

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1058
Re: Aligning record fields for SSE
« Reply #3 on: February 18, 2015, 11:13:37 am »
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

  • New Member
  • *
  • Posts: 19
Re: Aligning record fields for SSE
« Reply #4 on: February 18, 2015, 04:10:33 pm »
 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!!

 

TinyPortal © 2005-2018