Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »
Страницы: 1 2 3

Асм в FPC


Rouse_ ©   (15.02.17 13:58[20]

Умные люди тут говорят :)

function TRegion.PtInRegion(x, y: integer): boolean;
asm
 cmp x, self.rEX
 ja @@Out
 cmp x, self.rX
 jl @@Out
 cmp y, self.rEY
 ja @@Out
 cmp y, self.rY
 jl @@Out
 mov al, 01h
 jmp @@exit
@@Out:
 xor al, al
@@exit:
end;


dmk ©   (15.02.17 14:10[21]

Не, не хочет никак.
Может проблема в том, что это не класс, а record.
type
 PRegion = ^TRegion;
 TRegion = record
   private
     rX: integer; //Позиция слева
     rY: integer; //Позиция сверху
     rEX: integer; //Позиция справа
     rEY: integer; //Позиция снизу
     rW: integer; //Ширина включая первую точку
     rH: integer; //Высота включая первую точку
     procedure SetWidth(W: integer);
     procedure SetHeight(H: integer);
     procedure SetEX(EX: integer);
     procedure SetEY(EY: integer);
     function GetRect: TRect;
     procedure SetRect(R: TRect);
   public
     property X: integer read rX write rX;
     property Y: integer read rY write rY;
     property EX: integer read rEX write SetEX;
     property EY: integer read rEY write SetEY;
     property W: integer read rW write SetWidth;
     property H: integer read rH write SetHeight;
     procedure OffsetRegion(dx, dy: integer);
     function PtInRegion(x, y: integer): boolean;
     procedure ClipX(var x: integer);
     procedure ClipY(var y: integer);
     function InRangeX(x: integer): boolean;
     function InRangeY(y: integer): boolean;
     function OutRangeX(x: integer): boolean;
     function OutRangeY(y: integer): boolean;
     function RegionInRegion(R: TRegion): boolean;
     procedure Clear;
     function Empty: boolean;
     procedure AddPoint(dX, dY: integer);
     property Rect: TRect read GetRect write SetRect;
     procedure SwapX;
     procedure SwapY;
     procedure NormalizeX;
     procedure NormalizeY;
     procedure NormalizeXY;
  end;


Просто удобнее с записью чем с классом.


dmk ©   (15.02.17 14:13[22]

Сам он свой код так интерпретирует:

0000000100042954 488b45e8                 mov    -0x18(%rbp),%rax
0000000100042958 8b00                     mov    (%rax),%eax
000000010004295A 3b45f8                   cmp    -0x8(%rbp),%eax
000000010004295D 7f30                     jg     0x10004298f <PTINREGION+79>
000000010004295F 488b45e8                 mov    -0x18(%rbp),%rax
0000000100042963 8b4008                   mov    0x8(%rax),%eax
0000000100042966 3b45f8                   cmp    -0x8(%rbp),%eax
0000000100042969 7c24                     jl     0x10004298f <PTINREGION+79>
000000010004296B 488b45e8                 mov    -0x18(%rbp),%rax
000000010004296F 8b4004                   mov    0x4(%rax),%eax
0000000100042972 3b45f0                   cmp    -0x10(%rbp),%eax
0000000100042975 7f12                     jg     0x100042989 <PTINREGION+73>
0000000100042977 488b45e8                 mov    -0x18(%rbp),%rax
000000010004297B 8b400c                   mov    0xc(%rax),%eax
000000010004297E 3b45f0                   cmp    -0x10(%rbp),%eax
0000000100042981 7c06                     jl     0x100042989 <PTINREGION+73>
0000000100042983 c645e001                 movb   $0x1,-0x20(%rbp)
0000000100042987 eb0a                     jmp    0x100042993 <PTINREGION+83>
0000000100042989 c645e000                 movb   $0x0,-0x20(%rbp)
000000010004298D eb04                     jmp    0x100042993 <PTINREGION+83>
000000010004298F c645e000                 movb   $0x0,-0x20(%rbp)


Rouse_ ©   (15.02.17 14:21[23]

Ну тут даже не знаю как помочь, раз ты не хочешь отладчик в руки брать.


dmk ©   (15.02.17 14:39[24]

Да уже разобрался. У него переменная self слетает после первой проверки.
Если тупо rcx указать, то все в порядке.

function TRegion.PtInRegion(x, y: integer): boolean;
//if (x >= rX) and (x <= rEX) then result := (y >= rY) and (y <= rEY) else result := false;
asm
 cmp x, [rcx + rEX]
 jg @@Out
 cmp x, [rcx + rX]
 jl @@Out
 cmp y, [rcx + rEY]
 jg @@Out
 cmp y, [rcx + rY]
 jl @@Out
 mov al, 01h
 jmp @@Ex

@@Out:
 xor al, al

@@Ex:
end;


dmk ©   (15.02.17 14:40[25]

Работает раза в 2 быстрее чем код который генерит FPC или дельфи. Потому и нужен асм.
Приятно все закрутилось. Шустрее :)


dmk ©   (15.02.17 14:41[26]

И спасибо умным людям :) Пришлось убрать ret.


Rouse_ ©   (15.02.17 15:03[27]

Это всегда пожалуйста ;)


NoUser ©   (15.02.17 15:47[28]

> Пришлось убрать ret.
конечно, ты ж
.noframe
не пишешь.


> Работает раза в 2 быстрее чем код который генерит FPC или
> дельфи. Потому и нужен асм.

Потому и нужен диз-асм!, чтобы 'подсказать' компилятору что тебе нужно или увидеть правильно ли он тебя 'понял'.

А
function TRec.Test(x,y:Integer):Boolean; inline;
begin
Result := ( (x >= a) and (x <= b) and (y >= c) and (y <= d) );
end;

будет быстрее твоего асм и даже с .noframe


dmk ©   (15.02.17 17:20[29]

>будет быстрее твоего асм
Тут неверно.
Генерит медленный код. 2 чтения из памяти + сравнение * 4
против моих 4-х сравнений с памятью. У меня фпс в 2 раза поднимается почти с функцией на асм.


dmk ©   (15.02.17 17:22[30]

А за NoFrame спасибо! Еще быстре стала ;)


NoUser ©   (15.02.17 22:39[31]

> dmk ©   (15.02.17 17:20) [29]

странно, у тебя x,y перед вызовом тоже читаются и call/ret ещё запись/чтение.
( длина кода, правда, в ~2 раза меньше - сравнение reg,[reg] и короткие переходы - нужно будет затестить )


dmk ©   (16.02.17 02:04[32]

>нужно будет затестить
Уже: http://hostingkartinok.com/show-image.php?id=0fa7af40519ce173cc460d598dcbedad
Проц i7-6950X 3 ГГц. (20 ядер).

Функция A - на ассемблере.
Функция Б - на Delphi.

Почти в 2 раза ;)


dmk ©   (16.02.17 02:10[33]

Функция A
function TRegion.PtInRegion(x, y: integer): boolean;
asm
 cmp x, [rcx + rEX]
 jg @@Out
 cmp x, [rcx + rX]
 jl @@Out
 cmp y, [rcx + rEY]
 jg @@Out
 cmp y, [rcx + rY]
 jl @@Out
 mov al, 01h
 jmp @@Ex

@@Out:
 xor al, al

@@Ex:
end;


Функция Б
function TRegion.PtInRegion2(x, y: integer): boolean;
begin
 Result := (x >= rX) and (x <= rEX) and (y >= rY) and (y <= rEY);
end;


NoUser ©   (16.02.17 16:19[34]

> Проц i7-6950X 3 ГГц. (20 ядер).
ну-ну.

Сделай простой тест (rdtsc) на один поток.
У меня  Asm/Inline  ~ 19/15

~2х может быть только из-за ошибок в коде или логике.


dmk ©   (16.02.17 21:54[35]

у меня точный тест через READ TSC.
Я все функции тестирую на нем.


dmk ©   (16.02.17 23:21[36]

>ну-ну.
Дык многопоточная отрисовка у меня :) PaintStream фактически.
Тут же выкладывал: http://www.delphimaster.ru/cgi-bin/forum.pl?id=1486644466&n=5


dmk ©   (17.02.17 14:21[37]

По поводу ну-ну. Если взглянете в фотошоп, то в последних версиях (у меня CC 2017) во многих-многих местах уже многопоточность или использование GPU. У меня по тестам, даже неоптимизированный код Delphi в 8-10 раз быстрее выполняется. В оптимизированной версии кода есть случаи свыше 100%. Предсказание работает.


invis ©   (17.02.17 16:45[38]

Речь о том, что тестировать лучше в одном потоке, иначе непонятно, как воспринимать эти твои "почти 2 раза" - делить на 10? Или на 12 с учётом гипертрединга?
У меня в FPC быстрее паскалевский вариант со всеми оптимизациями и инлайном. Без инлайна примерно одинаково, несмотря даже на то, что компилятор генерирует более длинный asm-код.


dmk ©   (17.02.17 16:52[39]

>как воспринимать эти твои "почти 2 раза"
Там по ссылке результат теста. Кроме того возмущения непонятны. Нравится паскалевский вариант - ради бога. Руки никто никому не выламывает слава богу :)


Страницы: 1 2 3 версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо