Sign in Join

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

Mailing lists / fpc-devel / 2022-08

Question about memory alignment (again!)

6 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,

Recently I've made some optimisations centred around the SHR instruction on x86, and there was one pair of instructions that caught my attention:

movl (%rbx),%eax
shrl $24,%eax

Is it permissible to optimise this to (x86 is little-endian):

movzbl 3(%rbx),%eax?

(You could also optimise "movl; sarl" into a "movsbl" instruction this way)

Logically the result is the same and it removes an instruction and a pipeline stall, but will there be a performance hit that comes from reading an unaligned byte of memory like that?

I did make similar optimisation once before with QWords using the implicit zero-extension of the 32-bit MOV instruction - that is:

movq (%rbx),%rax
shrq $32,%rax

To:

movl 4(%rbx),%eax

This one is a little nicer though because it's still on a 32-bit boundary and so was permissible.

Gareth aka. Kit

Reply by email

Martin Frb
to J. Gareth Moreton
J. Gareth Moreton wrote 19 lines
Hi everyone, Recently I've made some optimisations centred around the SHR instruction on x86, and there was one pair of instructions that caught my attention: movl (%rbx),%eax shrl $24,%eax Is it permissible to optimise this to (x86 is little-endian): movzbl 3(%rbx),%eax? (You could also optimise "movl; sarl" into a "movsbl" instruction this way) Logically the result is the same and it removes an instruction and a pipeline stall, but will there be a performance hit that comes from reading an unaligned byte of memory like that?

Doesn't shr set the carry flag to the former bit 23? (the last shifted out) So its not the same, unless there is no dependency on the carry flag later on.

Show quoted text 13 lines
I did make similar optimisation once before with QWords using the implicit zero-extension of the 32-bit MOV instruction - that is: movq (%rbx),%rax shrq $32,%rax To: movl 4(%rbx),%eax This one is a little nicer though because it's still on a 32-bit boundary and so was permissible.

Same issue?

Reply by email

J. Gareth Moreton
to Martin Frb

That is indeed the case, yes - thanks for pointing it out (it also sets the zero flag if the register's final value is zero). In most cases, the code generator doesn't produce assembly language that uses the flags directly from SHR - instead it uses CMP and TEST instructions for that, which are only optimised out in the post-peephole stage.  Nevertheless, the existing optimisation does check to see if the FLAGS register is in use or not for safety.

That aside, might the memory alignment cause performance problems?

Gareth aka. Kit

Martin Frb wrote 45 lines
On 17/08/2022 02:21, J. Gareth Moreton via fpc-devel wrote: > Hi everyone, > > Recently I've made some optimisations centred around the SHR > instruction on x86, and there was one pair of instructions that > caught my attention: > > movl (%rbx),%eax > shrl $24,%eax > > Is it permissible to optimise this to (x86 is little-endian): > > movzbl 3(%rbx),%eax? > > (You could also optimise "movl; sarl" into a "movsbl" instruction > this way) > > Logically the result is the same and it removes an instruction and a > pipeline stall, but will there be a performance hit that comes from > reading an unaligned byte of memory like that? Doesn't shr set the carry flag to the former bit 23? (the last shifted out) So its not the same, unless there is no dependency on the carry flag later on. > > I did make similar optimisation once before with QWords using the > implicit zero-extension of the 32-bit MOV instruction - that is: > > movq (%rbx),%rax > shrq $32,%rax > > To: > > movl 4(%rbx),%eax > > This one is a little nicer though because it's still on a 32-bit > boundary and so was permissible. Same issue? _______________________________________________ fpc-devel maillist  -  https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Florian Klämpfl
to J. Gareth Moreton
Am 17.08.2022 um 14:12 schrieb J. Gareth Moreton. That aside, might the memory alignment cause performance problems?

I see no problem with the byte access, afaik byte accesses on any address are performance wise the same on x86.

Reply by email

Stefan Glienke
to J. Gareth Moreton: Recently I've made some optimisations centred around the SHR instruction on x86, and…

Interestingly this is what clang also does:

https://godbolt.org/z/Y4v14f9s3

Show quoted text 39 lines
On 17/08/2022 02:21 CEST J. Gareth Moreton via fpc-devel wrote: Hi everyone, Recently I've made some optimisations centred around the SHR instruction on x86, and there was one pair of instructions that caught my attention: movl (%rbx),%eax shrl $24,%eax Is it permissible to optimise this to (x86 is little-endian): movzbl 3(%rbx),%eax? (You could also optimise "movl; sarl" into a "movsbl" instruction this way) Logically the result is the same and it removes an instruction and a pipeline stall, but will there be a performance hit that comes from reading an unaligned byte of memory like that? I did make similar optimisation once before with QWords using the implicit zero-extension of the 32-bit MOV instruction - that is: movq (%rbx),%rax shrq $32,%rax To: movl 4(%rbx),%eax This one is a little nicer though because it's still on a 32-bit boundary and so was permissible. Gareth aka. Kit _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

J. Gareth Moreton
to Stefan Glienke

Thanks for the additional research.  I may be reinventing the wheel a bit with some of these discoveries.

Still, it feels good to beat gcc occasionally!

Gareth aka. Kit

Stefan Glienke wrote 48 lines
Interestingly this is what clang also does: https://godbolt.org/z/Y4v14f9s3 > On 17/08/2022 02:21 CEST J. Gareth Moreton via fpc-devel wrote: > > > Hi everyone, > > Recently I've made some optimisations centred around the SHR instruction > on x86, and there was one pair of instructions that caught my attention: > > movl (%rbx),%eax > shrl $24,%eax > > Is it permissible to optimise this to (x86 is little-endian): > > movzbl 3(%rbx),%eax? > > (You could also optimise "movl; sarl" into a "movsbl" instruction this way) > > Logically the result is the same and it removes an instruction and a > pipeline stall, but will there be a performance hit that comes from > reading an unaligned byte of memory like that? > > I did make similar optimisation once before with QWords using the > implicit zero-extension of the 32-bit MOV instruction - that is: > > movq (%rbx),%rax > shrq $32,%rax > > To: > > movl 4(%rbx),%eax > > This one is a little nicer though because it's still on a 32-bit > boundary and so was permissible. > > Gareth aka. Kit > > _______________________________________________ > fpc-devel maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email