Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2018-01

Data alignment feature

12 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

J. Gareth Moreton

Hi everyone,

So unless anyone has any objections, I would like to start experimenting to implement a feature that allows for per-type data alignment. The main purpose for this is to better support x86-64 SIMD extensions, where aligned data is far faster to process. While there is a compiler directive that enforces byte alignment, this risks causing conflicts with third party units and is a bit much of a demand for a programmer wishing to use an SIMD-tuned unit, say.

Bug/feature details: https://bugs.freepascal.org/view.php?id=32780

The format would be as follows:

type TypeName = TypeInfo [align ByteAmount];

The syntax for declaring a type is exactly the same, with a new optional "align" keyword before the terminating semicolon. "ByteAmount" has to be a power of 2, which I will probably limit to 128 currently, just so it doesn't cause ridiculous or malicious memory usage. There will probably have to be a minimum alignment as well, although this will probably just be automatically enforced (e.g. Single is always aligned on a 4-byte boundary minimum).

The intention here is that this feature will be a stepping stone for properly supporting vectorisation, implementing some form of the "M128" and "M256" types, and the "vectorcall" compiler directive for Windows.

Gareth aka. Kit

Reply by email

Florian Klämpfl
to J. Gareth Moreton: So unless anyone has any objections, I would like to start experimenting to implement a…
J. Gareth Moreton wrote 22 lines
Hi everyone, So unless anyone has any objections, I would like to start experimenting to implement a feature that allows for per-type data alignment. The main purpose for this is to better support x86-64 SIMD extensions, where aligned data is far faster to process. While there is a compiler directive that enforces byte alignment, this risks causing conflicts with third party units and is a bit much of a demand for a programmer wishing to use an SIMD-tuned unit, say. Bug/feature details: https://bugs.freepascal.org/view.php?id=32780 The format would be as follows: type TypeName = TypeInfo [align ByteAmount]; The syntax for declaring a type is exactly the same, with a new optional "align" keyword before the terminating semicolon. "ByteAmount" has to be a power of 2, which I will probably limit to 128 currently, just so it doesn't cause ridiculous or malicious memory usage. There will probably have to be a minimum alignment as well, although this will probably just be automatically enforced (e.g. Single is always aligned on a 4-byte boundary minimum). The intention here is that this feature will be a stepping stone for properly supporting vectorisation, implementing some form of the "M128" and "M256" types, and the "vectorcall" compiler directive for Windows.

In r38020 I committed a fix and an example tm128 how these records (m128/m256) can be implemented properly without any additional suffix. Please give it a try.

Reply by email

J. Gareth Moreton

Oh right. I see that you've opted to stick with the $codealign compiler directive. True, no new feature should be required, and TM128 shouldn't need to be redeclared by a third-party programmer.

In this case, I think this bug/feature report can be closed now: https://bugs.freepascal.org/view.php? id=32780 - unless you want the 'align' suffix.

Gareth aka. Kit.

On Mon 22/01/18 21:07 , Florian Klämpfl sent:

Show quoted text 60 lines
Am 19.01.2018 um 21:08 schrieb J. Gareth Moreton: > Hi everyone, > > So unless anyone has any objections, I would like to start experimenting to implement a feature that allows > for per-type data alignment. The main purpose for this is to better support x86-64 SIMD extensions, where > aligned data is far faster to process. While there is a compiler directive that enforces byte alignment, > this risks causing conflicts with third party units and is a bit much of a demand for a programmer wishing > to use an SIMD-tuned unit, say. > > Bug/feature details: https://bugs.freepascal.org/view.php?id=32780 > > The format would be as follows: > > type TypeName = TypeInfo [align ByteAmount]; > > The syntax for declaring a type is exactly the same, with a new optional "align" keyword before the > terminating semicolon. "ByteAmount" has to be a power of 2, which I will probably limit to 128 currently, > just so it doesn't cause ridiculous or malicious memory usage. There will probably have to be a minimum > alignment as well, although this will probably just be automatically enforced (e.g. Single is always aligned > on a 4-byte boundary minimum). > > The intention here is that this feature will be a stepping stone for properly supporting vectorisation, > implementing some form of the "M128" and "M256" types, and the "vectorcall" compiler directive for Windows. In r38020 I committed a fix and an example tm128 how these records (m128/m256) can be implemented properly without any additional suffix. Please give it a try. _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Adriaan van Os
to J. Gareth Moreton
J. Gareth Moreton wrote 5 lines
Oh right. I see that you've opted to stick with the $codealign compiler directive. True, no new feature should be required, and TM128 shouldn't need to be redeclared by a third-party programmer. In this case, I think this bug/feature report can be closed now: https://bugs.freepascal.org/view.php? id=32780 - unless you want the 'align' suffix.

I think two questions need to be answered, as there is more than just global variables

1. What is the status of alignment of the stack ?
2. I do think we need an alignment option in the FPC memory manager. Or at least a runtime-function that gets aligned memory, like
<http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_memalign.html>

Regards,

Adriaan van Os

Reply by email

J. Gareth Moreton

Florian has implemented a fix recently that allows for better memory alignment using $codealign - true though, I do think we need something to guarantee aligned memory from a function akin to GetMem, since one way or another, there is a performance penalty in using dynamic arrays over raw pointers (although it's not too bad).

Regarding the stack, when you first enter a function under x86-64, it is guaranteed to be 8 bytes away from a 16-byte boundary, because the stack is first aligned to a 16-byte boundary (Windows also allocates 32 bytes of shadow space, a multiple of 16), then the return address is pushed to the stack when you first call the function. However, normally the stack is then aligned to a 16-byte boundary, for any variables are put on the stack, because a stack frame is set up which includes pushing RBP to the stack.

For Florian's fix though, any local variables are given the correct alignment on the stack, even if the stack is unaligned beforehand.

Gareth aka. Kit

On Fri 26/01/18 15:41 , "Adriaan van Os" sent:

Show quoted text 38 lines
J. Gareth Moreton wrote: > Oh right. I see that you've opted to stick with the $codealign compiler directive. True, no new feature > should be required, and TM128 shouldn't need to be redeclared by a third-party programmer. > > In this case, I think this bug/feature report can be closed now: https://bugs.freepascal.org/view.php? > id=32780 - unless you want the 'align' suffix. I think two questions need to be answered, as there is more than just global variables 1. What is the status of alignment of the stack ? 2. I do think we need an alignment option in the FPC memory manager. Or at least a runtime-function that gets aligned memory, like <http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_ memalign.html> Regards, Adriaan van Os

Reply by email

J. Gareth Moreton

Sorry, something badly worded there. However, normally the stack is then aligned to a 16-byte boundary, BEFORE any variables are put on the stack, because a stack frame is set up which includes pushing RBP to the stack, hence aligning it.

On Fri 26/01/18 20:57 , "J. Gareth Moreton" sent:

Show quoted text 119 lines
Florian has implemented a fix recently that allows for better memory alignment using $codealign - true though, I do think we need something to guarantee aligned memory from a function akin to GetMem, since one way or another, there is a performance penalty in using dynamic arrays over raw pointers (although it's not too bad). Regarding the stack, when you first enter a function under x86-64, it is guaranteed to be 8 bytes away from a 16-byte boundary, because the stack is first aligned to a 16-byte boundary (Windows also allocates 32 bytes of shadow space, a multiple of 16), then the return address is pushed to the stack when you first call the function. However, normally the stack is then aligned to a 16-byte boundary, for any variables are put on the stack, because a stack frame is set up which includes pushing RBP to the stack. For Florian's fix though, any local variables are given the correct alignment on the stack, even if the stack is unaligned beforehand. Gareth aka. Kit On Fri 26/01/18 15:41 , "Adriaan van Os" z.nl sent: > J. Gareth Moreton wrote: > > > Oh right. I see that you've opted to stick with > the $codealign compiler directive. True, no new feature > > should be required, and TM128 shouldn't need to > be redeclared by a third-party programmer. > > > > > In this case, I think this bug/feature report > can be closed now: https://bugs.freepascal.org/view.php? > > id=32780 - unless you want the 'align' suffix. > > > > I think two questions need to be answered, as there is more than just > global variables > > > 1. What is the status of alignment of the stack ? > > 2. I do think we need an alignment option in the FPC memory manager. Or at > least a runtime-function > that gets aligned memory, like > > > memalign.html> > > > Regards, > > > > Adriaan van Os > > > > > _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Adriaan van Os
to J. Gareth Moreton: Florian has implemented a fix recently that allows for better memory alignment using…
J. Gareth Moreton wrote
Florian has implemented a fix recently that allows for better memory alignment using $codealign - true though, I do think we need something to guarantee aligned memory from a function akin to GetMem, since one way or another, there is a performance penalty in using dynamic arrays over raw pointers (although it's not too bad).

I have many objections against the built-in dynamic arrays and never use them.

For Florian's fix though, any local variables are given the correct alignment on the stack, even if the stack is unaligned beforehand.

That's good news. Can you give a small code example ? And I would suggest to add test-programs (checking the addeess of aligned global, heap and stack variables) to the fpc test-suite,

Regards,

Adriaan van Os

Reply by email

Jonas Maebe
to Adriaan van Os
Adriaan van Os wrote 6 lines
J. Gareth Moreton wrote: > For Florian's fix though, any local variables are given the correct > alignment on the stack, even if the stack is unaligned beforehand. That's good news. Can you give a small code example ?

The x86-64 ABIs mandate 16 byte alignment of the stack after the compiler-generated entry code.

And I would suggest to add test-programs (checking the addeess of aligned global, heap and stack variables) to the fpc test-suite,

There is already such a test program (except for heap, as we don't guarantee any alignment for heap-allocated memory and hence there is nothing to test).

Jonas

Reply by email

J. Gareth Moreton

On Sat 27/01/18 16:33 , Jonas Maebe sent:

Show quoted text 21 lines
Adriaan van Os wrote: > J. Gareth Moreton wrote: > >> For Florian's fix though, any local variables are given the correct >> alignment on the stack, even if the stack is unaligned beforehand. > > That's good news. Can you give a small code example ? The x86-64 ABIs mandate 16 byte alignment of the stack after the compiler-generated entry code.

That is true, but it's more the issue of, say, declaring a 4-byte variable and then a variable that must be aligned to a 16-byte boundary. Florian's test at tests/test/cg/tm128.pp confirms to see if the stack pointer is correctly decremented by 12 (or whatever the result of 16 minus the size of the previous variable) before reserving space for the aligned type.

Reply by email

Jonas Maebe
to J. Gareth Moreton
J. Gareth Moreton wrote 7 lines
On Sat 27/01/18 16:33 , Jonas Maebe sent: > > The x86-64 ABIs mandate 16 byte alignment of the stack after the > compiler-generated entry code. That is true, but it's more the issue of, say, declaring a 4-byte variable and then a variable that must be aligned to a 16-byte boundary.

That is implicit. The compiler always has aligned local variables to their declared alignment. There's only an issue if the ABI stack alignment is smaller than the variable's alignment, as the compiler currently does not have support to realign the stack to a custom alignment on entry.

Jonas

Reply by email

Adriaan van Os
to Jonas Maebe
Jonas Maebe wrote 5 lines
That is implicit. The compiler always has aligned local variables to their declared alignment. There's only an issue if the ABI stack alignment is smaller than the variable's alignment, as the compiler currently does not have support to realign the stack to a custom alignment on entry.

Yes, that's the issue I hinted on.

Regards,

Adriaan van Os

Reply by email