как заставить FPC генерить правильный SSE код

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Сообщение Sniper » 29.06.2005 14:10:44

Вобщем из-за багов с MMX решил помучать SSE =)
Устанавливаем {$FPUTYPE SSE} и начинаем мучать %-)

пишем такой код:
Код: Выделить всё
type
 TVector = record
 x, y, z: single;
 end;

function le_CrossVector(Vector1, Vector2: TVector): TVector;
begin
Result.X := (Vector1.Y * Vector2.Z) - (Vector1.Z * Vector2.Y);
Result.Y := (Vector1.Z * Vector2.X) - (Vector1.X * Vector2.Z);
Result.Z := (Vector1.X * Vector2.Y) - (Vector1.Y * Vector2.X);
end;

компилируем и получаем вот такой код:
Код: Выделить всё
.section .text
   .balign 4
   .balign 4
.globl   HEADERS_LE_CROSSVECTOR$TVECTOR$TVECTOR$$TVECTOR
HEADERS_LE_CROSSVECTOR$TVECTOR$TVECTOR$$TVECTOR:
   pushl   %ebp
   movl   %esp,%ebp
   subl   $36,%esp
   movl   %eax,-4(%ebp)
   movl   %edx,-8(%ebp)
   movl   %ecx,-12(%ebp)
   movl   -4(%ebp),%edx
   movl   (%edx),%eax
   movl   %eax,-24(%ebp)
   movl   4(%edx),%eax
   movl   %eax,-20(%ebp)
   movl   8(%edx),%eax
   movl   %eax,-16(%ebp)
   movl   -8(%ebp),%edx
   movl   (%edx),%eax
   movl   %eax,-36(%ebp)
   movl   4(%edx),%eax
   movl   %eax,-32(%ebp)
   movl   8(%edx),%eax
   movl   %eax,-28(%ebp)
   movss   -20(%ebp),%xmm1
   mulss   -28(%ebp),%xmm1
   movss   -16(%ebp),%xmm0
   mulss   -32(%ebp),%xmm0
   subss   %xmm0,%xmm1
   movl   -12(%ebp),%eax
   movss   %xmm1,(%eax)
   movss   -16(%ebp),%xmm0
   mulss   -36(%ebp),%xmm0
   movss   -24(%ebp),%xmm1
   mulss   -28(%ebp),%xmm1
   subss   %xmm1,%xmm0
   movl   -12(%ebp),%eax
   movss   %xmm0,4(%eax)
   movss   -24(%ebp),%xmm0
   mulss   -32(%ebp),%xmm0
   movss   -20(%ebp),%xmm1
   mulss   -36(%ebp),%xmm1
   subss   %xmm1,%xmm0
   movl   -12(%ebp),%eax
   movss   %xmm0,8(%eax)
   leave
   ret

Теперь если посмотреть Зубкова "Ассемблер для DOS, Windows и Unix"
то там мы видим что
movss - переслать одно вещественное число, что как понимаете не есть гуд

Я узнал на другом форуме, что если выровнять тип Tvector, и указать это компилятору, то будет генерироваться команда movaps что уже гораздо быстрее, так как она оперирует уже упакованными числами...
Вопрос: как выровнять данные так, чтобы генерировался более оптимальный SSE код?
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение SovNarKom » 29.06.2005 17:51:21

Sniper
Он вроде и так по 4 байта... Если бы был packed record, содержащий поля byte.

Вот потестил SSE, SSE2

Код: Выделить всё
{$FPUTYPE SSE}
// NOSSE 25812
// SSE 25828
// DOUBLE 67532
// DOUBLESSE 67485
// DOUBLESSE2 SIGSERV ERROR %)
program sse;

uses windows;
type
TVector = record
x, y, z: single;
end;

function le_CrossVector(Vector1, Vector2: TVector): TVector;
begin
Result.X := (Vector1.Y * Vector2.Z) - (Vector1.Z * Vector2.Y);
Result.Y := (Vector1.Z * Vector2.X) - (Vector1.X * Vector2.Z);
Result.Z := (Vector1.X * Vector2.Y) - (Vector1.Y * Vector2.X);
end;

var
a,b,c: TVector;
i,g: integer;

begin
g:=GetTickCount;
for i:=0 to 1000000000 do a:=le_CrossVector(b,c);
writeln(GetTickCount-g);
readln;
end.



Да... SSE...
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение SovNarKom » 29.06.2005 17:56:44

Хотя лучше это конечно оформить как процедуру и передавать указатели...

Код: Выделить всё
// proc 28109
// procSSE 27532
// procSSE2 27516


Нееет!? Непонял! Как! проверяем в Delphi6 - > 7672!!! Огогогого!
Если функция - 21500!!!

FPC 1.9.8 :(
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение SovNarKom » 29.06.2005 18:17:07

Уффф! Поставил все настройки на максимум скорости

Код: Выделить всё
proc 13532
procSSE 16391
procSSE2 16328

Везде Single.
Продолжаю тесты...

С опциями
Код: Выделить всё
-S2cgi -CX -Og3r -gl -Xs -XX -vewnhi -l -Fu.

результат 11635! Заметьте -Og
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение Sniper » 29.06.2005 18:31:00

SovNarKom
// NOSSE 25812
// SSE 25828
// DOUBLE 67532
// DOUBLESSE 67485

Не выразительный какой-то SSE... т.е вполне укладывается в погрешность разница вычислений с и без SSE...
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение Sniper » 29.06.2005 18:31:48

SSE2 - предназначен для работы с Double =)

>>Поставил все настройки на максимум скорости
Это какие может я не все ставлю? У меня: -OG3p3ru что ещё поставить?
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение Sniper » 29.06.2005 18:59:33

У меня получились очень интересные результаты =)
Исходник из второго поста:

Процессор: Pentium M 1.7GHz (sse, sse2)
FPU - Single - 108385
SSE - Single - 28220
SSE2 - Double - 107725

Улыбают меня такие результаты =)
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение SovNarKom » 29.06.2005 19:20:37

Sniper
вот второй исходник у меня AthlonXP 1902MHz(разогнанный, шина 333)
Из лазаруса... Тьфу я во втором посте забыл SSE2 выложить... -> <span style='color:red'>fixed</span> :)
FPU 80735
SSE 80718!

Мои опции
Код: Выделить всё
-S2cgi -CX -Og3r -gl -Xs -XX -vewnhi -l


видать в 1.9.8 с SSE туго, пробую FPC 2.0.0...
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение Sniper » 29.06.2005 19:41:44

Пропробуй -Og3ru или вот так вообще -OG3p3ru
У меня версия из Daily Snapshot 2.1.x от 20.06
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение SovNarKom » 29.06.2005 19:56:19

При любых быстрых(моих, твоих) результат около 25400
Delphi6 - 21100 :(
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение SovNarKom » 29.06.2005 20:00:03

-Og3ru

SSE 81500 ...

-OG3p3ru

SSE 24438
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение Sniper » 29.06.2005 20:13:30

Проц: Athlon 1000MHz (L2 256Kb cache)
Только: FPU
Переменная: Single

Delphi7 - 41407!!
FPC 2.1.x 20.06 -OG3p3ru - 40610!!
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение SovNarKom » 29.06.2005 20:21:17

смотри как получается
-OG3p3ru
22796!
НО если работать с указателями: 14531


-CX -Og3ru -gl -Xs -XX
26313
С указателями 11678

а, да вот новый код

Код: Выделить всё
program sse;

uses windows;
type
pTVector = ^TVector;
TVector = record
 x, y, z: single;
end;

procedure le_CrossVector(Vector1, Vector2, VectRes: pTVector);  overload;
begin
VectRes^.X := (Vector1^.Y * Vector2^.Z) - (Vector1^.Z * Vector2^.Y);
VectRes^.Y := (Vector1^.Z * Vector2^.X) - (Vector1^.X * Vector2^.Z);
VectRes^.Z := (Vector1^.X * Vector2^.Y) - (Vector1^.Y * Vector2^.X);
end;

function le_CrossVector(Vector1, Vector2: TVector): TVector; overload;
begin
result.X := (Vector1.Y * Vector2.Z) - (Vector1.Z * Vector2.Y);
result.Y := (Vector1.Z * Vector2.X) - (Vector1.X * Vector2.Z);
result.Z := (Vector1.X * Vector2.Y) - (Vector1.Y * Vector2.X);
end;

procedure le_CrossVector(var Vector1, Vector2, VectRes: TVector); overload;
begin
VectRes.X := (Vector1.Y * Vector2.Z) - (Vector1.Z * Vector2.Y);
VectRes.Y := (Vector1.Z * Vector2.X) - (Vector1.X * Vector2.Z);
VectRes.Z := (Vector1.X * Vector2.Y) - (Vector1.Y * Vector2.X);
end;

var
a,b,c: TVector;
i,g: integer;

begin
g:=GetTickCount;
for i:=0 to 1000000000 do le_CrossVector(b,c,a);
writeln(GetTickCount-g);
readln;
end.
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение Sniper » 29.06.2005 20:22:24

Покажи код с указателями!!
Я пока готовлю глобальный тест
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение SovNarKom » 29.06.2005 20:39:10

Короче оптимально для меня наверное
Код: Выделить всё
-S2cgi -Og3ru -CX -Xs -XX

+Strip +UPX = 12Kb - Это мне уже нравится. С указателями 12703.
Зато без них 78375 :(((
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10

Рейтинг@Mail.ru