Вопросы программирования на Free Pascal, использования компилятора и утилит.
Модератор: Модераторы
vitya007 » 18.01.2015 20:26:03
Почему компилятор делает код который работает через стэк с самыми простыми операциями?
Если кто может, помогите найти самые производительные параметры для компиляции
- Код: Выделить всё
program lol;
uses Windows;
type
DWORD = Cardinal;
//{$FPUTPYE SSE2}
function Test: DWORD;
var mem: Pointer;
t, i: DWORD;
begin
asm
int3
end;
i := 0;
t := GetTickCount;
while i < (1 shl 20) do
begin
getmem(mem, 1);
freemem(mem, 1);
inc(i);
end;
Test := GetTickCount - t;
end;
function Test2: DWORD;
var
i, t: DWORD;
v: single;
begin
asm
int3
end;
v := 0;
t := GetTickCount;
i := 0;
while i < (1 shl 20) do
begin
v := v * 0.00001;
inc(i);
end;
Test2 := GetTickCount - t;
end;
begin
writeln(test);
readln;
end.
Тест функции "Test"
FPC asm
- Код: Выделить всё
CPU Disasm
Address Hex dump Command Comments
004013F0 55 PUSH EBP
004013F1 89E5 MOV EBP,ESP
004013F3 83EC 10 SUB ESP,10
004013F6 CC INT3
004013F7 C745 F0 0000000 MOV DWORD PTR SS:[EBP-10],0
004013FE E8 4DFCFFFF CALL <JMP.&kernel32.GetTickCount> ; Jump to kernel32.GetTickCount
00401403 8945 F4 MOV DWORD PTR SS:[EBP-0C],EAX
00401406 EB 1D JMP SHORT 00401425
00401408 8D45 F8 LEA EAX,[EBP-8]
0040140B BA 01000000 MOV EDX,1
00401410 E8 FB230000 CALL 00403810
00401415 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00401418 BA 01000000 MOV EDX,1
0040141D E8 0E240000 CALL 00403830
00401422 FF45 F0 INC DWORD PTR SS:[EBP-10]
00401425 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]
00401428 3D 00001000 CMP EAX,100000
0040142D ^ 72 D9 JB SHORT 00401408
0040142F E8 1CFCFFFF CALL <JMP.&kernel32.GetTickCount> ; Jump to kernel32.GetTickCount
00401434 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-0C]
00401437 29D0 SUB EAX,EDX
00401439 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
0040143C 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
0040143F C9 LEAVE
00401440 C3 RETN
dcc32 v28 asm
- Код: Выделить всё
CPU Disasm
Address Hex dump Command Comments
00405B14 53 PUSH EBX
00405B15 56 PUSH ESI
00405B16 57 PUSH EDI
00405B17 CC INT3
00405B18 33DB XOR EBX,EBX
00405B1A E8 89FFFFFF CALL <JMP.&kernel32.GetTickCount> ; Jump to kernel32.GetTickCount
00405B1F 8BF8 MOV EDI,EAX
00405B21 B8 01000000 MOV EAX,1
00405B26 E8 11D1FFFF CALL 00402C3C
00405B2B 8BF0 MOV ESI,EAX
00405B2D 8BC6 MOV EAX,ESI
00405B2F E8 24D1FFFF CALL 00402C58
00405B34 43 INC EBX
00405B35 81FB 00001000 CMP EBX,100000
00405B3B ^ 72 E4 JB SHORT 00405B21
00405B3D E8 66FFFFFF CALL <JMP.&kernel32.GetTickCount> ; Jump to kernel32.GetTickCount
00405B42 2BC7 SUB EAX,EDI
00405B44 5F POP EDI
00405B45 5E POP ESI
00405B46 5B POP EBX
00405B47 C3 RETN
-
vitya007
- новенький
-
- Сообщения: 32
- Зарегистрирован: 10.05.2011 22:23:27
Дож » 18.01.2015 22:41:14
Я не понял в чём вопрос. Вы спрашиваете почему функции GetMem и FreeMem принимают аргументы через стек?
-

Дож
- энтузиаст
-
- Сообщения: 900
- Зарегистрирован: 12.10.2008 16:14:47
vitya007 » 18.01.2015 23:43:37
даже дело не в функциях, а в обычном цикле
FPC
- Код: Выделить всё
00401422 FF45 F0 INC DWORD PTR SS:[EBP-10]
00401425 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]
00401428 3D 00001000 CMP EAX,100000
dcc32 v28
- Код: Выделить всё
00405B34 43 INC EBX
00405B35 81FB 00001000 CMP EBX,100000
-
vitya007
- новенький
-
- Сообщения: 32
- Зарегистрирован: 10.05.2011 22:23:27
Дож » 19.01.2015 01:00:23
Я могу ошибаться, но, возможно, проблема кроется в int3: fpc видит ручное ассемблерное вмешательство и боится держать локальные переменные в регистре.
-

Дож
- энтузиаст
-
- Сообщения: 900
- Зарегистрирован: 12.10.2008 16:14:47
vitya007 » 19.01.2015 02:14:58
Дож писал(а):Я могу ошибаться, но, возможно, проблема кроется в int3: fpc видит ручное ассемблерное вмешательство и боится держать локальные переменные в регистре.
Ха, точно и странно.
FPC asm for
- Код: Выделить всё
CPU Disasm
Address Hex dump Command Comments
0040141D /EB 1B JMP SHORT 0040143A ; Go Start For
0040141F |8D45 FC LEA EAX,[EBP-4]
00401422 |BA 01000000 MOV EDX,1
00401427 |E8 F4230000 CALL 00403820 ; GetMem
0040142C |8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
0040142F |BA 01000000 MOV EDX,1
00401434 |E8 07240000 CALL 00403840 ; FreeMem
00401439 |46 INC ESI
0040143A 81FE 00001000 CMP ESI,100000
00401440 ^ 72 DD JB SHORT 0040141F
Спасибо
Еще вопросик, SSE инструкции с векторами без asm возможно?
-
vitya007
- новенький
-
- Сообщения: 32
- Зарегистрирован: 10.05.2011 22:23:27
Дож » 19.01.2015 02:32:06
Попробуйте -CfSSE:
- Код: Выделить всё
C:\data\temp>cat vector.pas
procedure Sum(const A, B: TVector; var C: TVector);
var
I: Integer;
begin
for I := 0 to 3 do
C[I] := A[I] + B[I];
end;
var
A, B, C: TVector;
begin
Sum(A, B, C);
Writeln(C[0], C[1], C[2], C[3]);
end.
C:\data\temp>fpc -al -gl vector.pas >dev.null && cp vector.s original.s
C:\data\temp>fpc -CfSSE -al -gl vector.pas >dev.null && cp vector.s sse.s
C:\data\temp>diff original.s sse.s
92,93c92,93
< flds (%eax,%edx,4)
< fadds (%ecx,%ebx,4)
---
> movss (%ecx,%ebx,4),%xmm0
> addss (%eax,%edx,4),%xmm0
96c96
< fstps (%edx,%eax,4)
---
> movss %xmm0,(%edx,%eax,4)
Хотя я помню, что есть много жалоб на поддержку SSE в FPC, в частности тут:
viewtopic.php?t=9432
-

Дож
- энтузиаст
-
- Сообщения: 900
- Зарегистрирован: 12.10.2008 16:14:47
vitya007 » 19.01.2015 19:34:50
Спасибо за ответы
-
vitya007
- новенький
-
- Сообщения: 32
- Зарегистрирован: 10.05.2011 22:23:27
Вернуться в Free Pascal Compiler
Кто сейчас на конференции
Сейчас этот форум просматривают: Google [Bot], Yandex [Bot] и гости: 5