Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Разное
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 11.03.2013, 13:02
Аватар для vvvch
vvvch vvvch вне форума
Прохожий
 
Регистрация: 28.03.2012
Адрес: г.Боровичи, Новг. обл.
Сообщения: 19
Версия Delphi: Lazarus
Репутация: 10
По умолчанию Помогите пожалуйста с профилированием

Я не большой специалист в программировании и много не знаю. Сделал две функции (метода) одна на паскале, другая на ассемблере. Они почти одинаковые, делают одно и то-же (вычисляют контрольную сумму (СRС16) для Modbus) Они работают правильно - я проверял, но... Я не знаю стоит-ли использовать ассемблер для ускорения или не заморачиваться с этим и делать на паскале. Когда - то, я помню, время выполнения пожно было выяснить профилированием, но это под дос, а сейчас у меня таких инструментов нет. Вот я и привожу текст функций, если у кого он(профайлер) есть выясните пожалуйста стоит ли использовать паскаль или ассемблер версию (или это всё равно). Функция будет вызываться очень часто, параметром будет буфер не более 100 байт (очень редко больше).
Вот функции:
Код:
function TfCalcCRC.CalcCRC(var buf : array of byte; const len : integer) : word;
  // CRC = $CB72   $0924
type
  TWord = record
    lo, hi  : byte
  end;
var
  i : integer;
  j : byte;
const
  CRC_st = $FFFF;
  CRC_1  = $A001;
begin
  Result := CRC_st;
  for i := 0 to len - 1 do
  begin
    TWord(Result).lo := TWord(Result).lo xor Buf[i];
    for j := 0 to 7 do
      if boolean(Result and 1) then
        Result := (Result shr 1) xor CRC_1
      else
        Result := Result shr 1;
  end;
end;

{$ASMMODE intel}
//{$OUTPUT_FORMAT BASM}
function TfCalcCRC.CalcCRCasm(var buf : array of byte; const len : integer) : word;
  assembler;
const
  CRC_st = $FFFF;
  CRC_1  = $A001;
asm
   //EDX - Указывает на передаваемые параметры
   //Можно менять EAX ECX ??EDX
   //Сохранить в стэке EBX ESI EDI ESP EBP не менять DS ES SS CS FS GS
   PUSH ESI
   MOV     AX, CRC_st  //AX - Result
   XOR     ESI, ESI    //ESI - цикл по буферу 0,1,2...len-1
@loop1:
   XOR     AL, byte ptr [buf+ESI] //TWord(Result).lo := TWord(Result).lo xor Buf[i];
   MOV CX, 8 //цикл 8 раз
@loop2:
   //if boolean(Result and 1) then
   TEST AX, 1 //and с установкой флагов без изменения акамулятора
   JZ @m1 //Переход если 0
   SHR AX, 1 //Result := (Result shr 1) xor CRC_1
   XOR AX, CRC_1
   JMP @m2
@m1: // Result := Result shr 1;
   SHR AX, 1
@m2:
   LOOP @loop2
   INC     ESI                // Организуем т.о
   CMP     ESI, dword ptr len // цикл по буферу
   JB      @loop1              // --------------
   //в AX -  результат
   //
   pop ESI
end;                            
Я не большой специалист в программировании, по этому если увидите ошибки (а их наварно не мало) сообщите.
Для профилирования я написал небольшую отладочную програмку но она на Lazarus (впрочем это не важно ассемблер вроде не использует ничего, что не работало бы под Delphi). Файл я приложил.
Очень прошу - помогите.
Вложения
Тип файла: rar CRC.rar (125.2 Кбайт, 1 просмотров)
Ответить с цитированием
  #2  
Старый 11.03.2013, 13:22
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Лучше не заморачиваться, например если ф-ю на ассемблере придется перепиливать под х64 - будет гемор, а которая на паскале - нет.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #3  
Старый 11.03.2013, 14:13
Аватар для vvvch
vvvch vvvch вне форума
Прохожий
 
Регистрация: 28.03.2012
Адрес: г.Боровичи, Новг. обл.
Сообщения: 19
Версия Delphi: Lazarus
Репутация: 10
По умолчанию

А почему код (асемблерный) должен отличаться для 32 и 64 разрядной версии? Вроде те регистры что 32 разрядные и там будут так-же работать. Правда как там осуществляется адресация памяти (разница) я не знаю. Но в данном случае код будет работать под WinXP Pro (32бит) Переход на 64разрядную пока не планируется.
Ответить с цитированием
  #4  
Старый 11.03.2013, 14:19
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Для профилирования можно использовать AQTime, хотя ассемблер в данном случае большого прироста скорости не даст - не тот случай.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #5  
Старый 11.03.2013, 14:43
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

Ну как вариант -
во первых - команда SHR вырабатывает флаг CF, если "выдвигаемый" разряд равен единице, тогда внутренний цикл можно подсократить - убрать команду сравнения и один переход

Код:
@loop2:    
  SHR AX, 1
  JNB @m2
  XOR AX, CRC_1    
@m2: 
  LOOP @loop2

Во вторых - этот внутренний цикл можно развернуть - просто переписать восемь раз. Тогда уберётся команда LOOP и освободится регистр ECX.
Ну и счётчик внешнего цикла тоже лучше сделать в регистре.
Ответить с цитированием
  #6  
Старый 11.03.2013, 15:01
Аватар для vvvch
vvvch vvvch вне форума
Прохожий
 
Регистрация: 28.03.2012
Адрес: г.Боровичи, Новг. обл.
Сообщения: 19
Версия Delphi: Lazarus
Репутация: 10
По умолчанию

Цитата:
Сообщение от icWasya
Ну как вариант -
во первых - команда SHR вырабатывает флаг CF, если "выдвигаемый" разряд равен единице, тогда внутренний цикл можно подсократить - убрать команду сравнения и один переход

Код:
@loop2:    
  SHR AX, 1
  JNB @m2
  XOR AX, CRC_1    
@m2: 
  LOOP @loop2

Во вторых - этот внутренний цикл можно развернуть - просто переписать восемь раз. Тогда уберётся команда LOOP и освободится регистр ECX.
Ну и счётчик внешнего цикла тоже лучше сделать в регистре.


Огромное СПАСИБО!!! Я не очень хорошо знаю ассемлер и долго с этим мучился (пытался подсократить). СПАСИБО!
Ответить с цитированием
  #7  
Старый 11.03.2013, 15:40
Аватар для vvvch
vvvch vvvch вне форума
Прохожий
 
Регистрация: 28.03.2012
Адрес: г.Боровичи, Новг. обл.
Сообщения: 19
Версия Delphi: Lazarus
Репутация: 10
По умолчанию

Цитата:
Сообщение от icWasya
Ну и счётчик внешнего цикла тоже лучше сделать в регистре.
Код:
   INC     ESI                // Организуем т.о
   CMP     ESI, dword ptr len // цикл по буферу
   JB      @loop1              // --------------

А ведь счётчик и сделан в ESI это только проверка с памятью. Или её (проверку) тоже в освободившийся ECX?
Ответить с цитированием
  #8  
Старый 11.03.2013, 16:07
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

команда loop работает с регистром ecx.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #9  
Старый 11.03.2013, 16:11
Аватар для vvvch
vvvch vvvch вне форума
Прохожий
 
Регистрация: 28.03.2012
Адрес: г.Боровичи, Новг. обл.
Сообщения: 19
Версия Delphi: Lazarus
Репутация: 10
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
команда loop работает с регистром ecx.

Да, но приращение идёт max, ...,3,2,1 выход. А мне, для работы с буфером, нужно 0,1,2,3,..., max-1.
Ответить с цитированием
  #10  
Старый 11.03.2013, 16:51
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Ну так вычитать из каунта ecx-i
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #11  
Старый 11.03.2013, 17:04
Аватар для vvvch
vvvch vvvch вне форума
Прохожий
 
Регистрация: 28.03.2012
Адрес: г.Боровичи, Новг. обл.
Сообщения: 19
Версия Delphi: Lazarus
Репутация: 10
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
Ну так вычитать из каунта ecx-i

это как???
Приведите пожалуйста пример.
На самом деле я тоже обдумывал эти варианты, но тут появлыются "лишние" комманды. Проще просто инкрементировать регистр и проверить (cmp) его, выйти если условие не выполняется.
Ответить с цитированием
  #12  
Старый 11.03.2013, 17:09
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Слушайте, зачем весь этот изврат с сокращением кода? Не так уж и критично если будет на паскале написана ф-я.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #13  
Старый 11.03.2013, 17:36
Аватар для vvvch
vvvch vvvch вне форума
Прохожий
 
Регистрация: 28.03.2012
Адрес: г.Боровичи, Новг. обл.
Сообщения: 19
Версия Delphi: Lazarus
Репутация: 10
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
Слушайте, зачем весь этот изврат с сокращением кода? Не так уж и критично если будет на паскале написана ф-я.

Это конечно правильно. Но... всё-таки интересно сократить. Хотя это уже не имеет практического значения. Чистый "изврат". Если надоело - бросьте.
А я подумал вот о чём
Код:
...
xor ECX, ECX
mov ECX, dword ptr len
mov ESI, ECX
...
@loop1:
...
mov al, byte ptr [buf+ESI-ECX] //на самом деле не mov a xor ну не важно, принцып
...
loop @loop1
...

Правда тут встаёт вопрос насколько мы съэкономим время при вычислении [buf+ESI-ECX]? Может быть кто знает?
Ответить с цитированием
  #14  
Старый 11.03.2013, 17:55
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Можно же замерять.
Забыл какая ф-я до наносекунд может посчитать промежуток, завтра на работе пороюсь - скину.

Чето со спаркой с getsystemfrequency.

Вспомнил, QueryPerformanceCounter и QueryPerformanceFrequency.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию

Последний раз редактировалось M.A.D.M.A.N., 11.03.2013 в 17:57.
Ответить с цитированием
  #15  
Старый 11.03.2013, 18:22
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Я бы делал как-то так:
Код:
   push esi
   mov  bx, CRC_st  //bX - Result
   mov  ecx, len
   mov  esi, buf
   cld
@loop1:
   lodsb
   xor  bl, al
   mov edx, 8 //цикл 8 раз
@loop2:
     shr bx, 1
     jc @m2
     xor bx, CRC_1
  @m2:
     dec edx
     jnz    @loop2
   dec ecx
   Jnz    @loop1 
   mov ax, bx
   pop esi
Насколько я знаю, lodsb нехило прокачан - всегда одни и те же регистры и не надо считать адрес. xor двух регистров опять же быстрее, чем xor с памятью. Так что вполне мб это скажется лучше.
Но в любом случае, inc и cmp надо было убирать любыми методами. Это самое медленное в коде.
А вариант с
Цитата:
mov al, byte ptr [buf+ESI-ECX] //на самом деле не mov a xor ну не важно, принцып
не прокатит, регистр нельзя вычитать в адресе.

Цитата:
Слушайте, зачем весь этот изврат с сокращением кода? Не так уж и критично если будет на паскале написана ф-я.
Вот если бы сравнивать студию и самопальный асм, то разницы не было бы вообще (0-2 команды). А вот делфа умеет компилить так, что разница по качеству в пользу самопала может быть в два-три раза. Если считать надо ну очень часто, это может сказаться на общей скорости процентов на 5. Когда я писал одну прогу, 5 процентов были двумя-тремя секундами.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 11.03.2013 в 18:31.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:35.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter