Registers in loops

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Registers in loops

denisgolovan
Hi all

Recently I discovered that fpc refuses to use registers in my loops even with optimization turned on (-O1,-O3 used).
I tested using both Linux x86 and Windows x64 version.

The results are basically the same.
The compiler just uses stack variables.

I've also included naive asm version of the same loop just to see the comparison.
All tests were done using EpikTimer.

======================================
Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz
Sandy Bridge-DT XE
Microsoft Windows XP Professional x64 Edition Build 3790
Free Pascal Compiler version 2.7.1 [2012/08/25] for x86_64
Result:
 
asm 0.0256358138703286 sec
for downto 0.193564002384441 sec
for to 0.177300077002942 sec
repeat 0.158137833298043 sec
while 0.156996773175159 sec

Intel(R) Core(TM)2 CPU 6600  @ 2.40GHz
Linux x86
Free Pascal Compiler version 2.7.1 [2012/11/17] for i386
Result:

asm 0.049642 sec
for downto 0.322694 sec
for to 0.312163 sec
repeat 0.298781 sec
while 0.298575 sec
======================================

You can easily see that asm version is about 10 times faster.
Is this something that can be fixed?

P.S. A full test source + assembler listings are attached.

 --
Regards,
Denis Golovan
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

loop-test.tar.gz (25K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Registers in loops

leledumbo
Administrator
Maybe we don't have such optimization yet?
Reply | Threaded
Open this post in threaded view
|

Re: Registers in loops

patspiper
In reply to this post by denisgolovan
On 13/12/12 21:51, denisgolovan wrote:
> Hi all
>
> Recently I discovered that fpc refuses to use registers in my loops even with optimization turned on (-O1,-O3 used).
With the asm code commented out and without any optimization, the
registers are used.

.Ll12:
# [47] for i:=1 to 100000000 do
     movl    $1,%ebx
     decl    %ebx
     .balign 4,0x90
.Lj80:
     incl    %ebx
.Ll13:
# [48] Inc(i2);
     incl    %eax
.Ll14:
     cmpl    $100000000,%ebx
     jb    .Lj80
...
.Ll18:
# [53] i:=1;
     movl    $1,%ebx
     .balign 4,0x90
.Lj111:
.Ll19:
# [55] Inc(i);
     incl    %ebx
.Ll20:
# [56] until i>100000000;
     cmpl    $100000000,%ebx
     jna    .Lj111
...
.Ll24:
# [61] i:=1;
     movl    $1,%ebx
.Ll25:
# [62] while i<100000000 do
     jmp    .Lj145
     .balign 4,0x90
.Lj144:
.Ll26:
# [63] Inc(i);
     incl    %ebx
.Lj145:
.Ll27:
     cmpl    $100000000,%ebx
     jb    .Lj144

Stephano
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Registers in loops

Jonas Maebe-2

On 14 Dec 2012, at 09:26, patspiper wrote:

> On 13/12/12 21:51, denisgolovan wrote:
>> Hi all
>>
>> Recently I discovered that fpc refuses to use registers in my loops  
>> even with optimization turned on (-O1,-O3 used).
> With the asm code commented out and without any optimization, the  
> registers are used.

Indeed, adding inline assembler to a routine disables many  
optimizations.


Jonas

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Registers in loops

michael.vancanneyt


On Fri, 14 Dec 2012, Jonas Maebe wrote:

>
> On 14 Dec 2012, at 09:26, patspiper wrote:
>
>> On 13/12/12 21:51, denisgolovan wrote:
>>> Hi all
>>>
>>> Recently I discovered that fpc refuses to use registers in my loops even
>>> with optimization turned on (-O1,-O3 used).
>> With the asm code commented out and without any optimization, the registers
>> are used.
>
> Indeed, adding inline assembler to a routine disables many optimizations.

Doesn't adding the list of modified registers to the 'ASM' block
help in this case ? I thought this was why we supported this ?

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Registers in loops

Jonas Maebe-2

On 14 Dec 2012, at 13:46, [hidden email] wrote:

On Fri, 14 Dec 2012, Jonas Maebe wrote:

Indeed, adding inline assembler to a routine disables many optimizations.

Doesn't adding the list of modified registers to the 'ASM' block
help in this case ? I thought this was why we supported this ?

That's required to guarantee the correctness of the generated code under all circumstances. It doesn't help with register variables though:

{$asmmode intel}
procedure test;
var
  l: longint;
begin
  // compiler decides to put l into register eax
  l:=1;
  asm
    push eax
    push edx
    rdtsc
    mov  l,eax
    pop edx
    pop eax
  end; // no register changed -> no list required
  // always writes 1
  writeln(l);
end;

It would be possible to prevent registers accessed from assembler code to be put into registers, but currently the compiler does not perform any kind of analysis of assembler code, and I think it should stay that way. There are too many ways in which assembler code can be written that defeats automatic analyses. If you use assembler, you get full freedom and that freedom gets taken away from the compiler.


Jonas

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal