Скорость выполнения Asm Vs Delphi

Тема в разделе "WASM.BEGINNERS", создана пользователем lilongue, 12 мар 2008.

  1. lilongue

    lilongue New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2008
    Сообщения:
    2
    Встал вопрос об использовании ассемблерных вставок в Delphi с целью повышения быстродействия.
    Решил проверить, будет ли выигрыш на элементарном примере.
    Оказалось, что
    Код (Text):
    1.  sum : integer;
    2. dat1, dat2 : TDateTime;
    3. label a;
    4. begin
    5. dat1 := now;
    6. asm
    7.   mov ecx, 1000000000
    8.   xor eax, eax
    9.   a:
    10.   add eax, 1
    11.   loop a
    12.   mov [sum], eax
    13. end;
    14. dat2 := now;
    работает в 4 раза медленнее чем
    Код (Text):
    1. i : integer;
    2. sum : integer;
    3. dat1, dat2 : TDateTime;
    4. begin
    5.   dat1 := now;
    6.   i := 1000000000;
    7.   sum := 0;
    8.   while (i > 0) do
    9.   begin
    10.     sum := sum + 1;
    11.     i := i - 1;
    12.   end;
    13.   dat2 := now;
    в чем косяк?
     
  2. Money_Man

    Money_Man New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2008
    Сообщения:
    2
    попробуй заменить строку add eax, 1 на inc eax.
    Должно отработать быстрее.

    Но почему идет такой проигрыш во времени я чесно говоря не знаю
     
  3. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    lilongue
    loop - не самая быстрая операция
    замени ее на dec ecx/jnz a
    а вообще-то для большой скорости помни, что АЛУ в процессоре не одно, и что есть такая штука, как конвеер
    твой код можно ускорить
    Код (Text):
    1. mov ecx, 1000000000/4
    2.   xor eax, eax
    3.   xor ebx,ebx
    4.   xor edi,edi
    5.   xor esi,esi
    6.   a:
    7.   add eax, 1
    8.   add ebx,1
    9.   add esi,1
    10.   add edi,1
    11.   sub ecx,1
    12.   jnz a
    13.   mov [sum], eax
    14.   add [sum],ebx
    15.   add [sum],esi
    16.   add [sum],edi
     
  4. zoool

    zoool New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2007
    Сообщения:
    412
    мужики, не ищите суслика там, где его нет
    Смотрим внимательно на типы

    i - int (короткое с учетом знака)
    eax - грубо говоря unsigned long

    число проходов петли во втором примере меньше

    Топикстартер: замени тип i на DWORD
     
  5. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    zoool, unsigned long - это из другой оперы. В этой же опере оно уже лет 10 как называется cardinal. Или просто DWORD.

    integer в Delphi 32-битный. Нафига родоначальник темы использовал while i>0 вместо традиционного в таких случаях for - тоже непонятно.
     
  6. zoool

    zoool New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2007
    Сообщения:
    412
    CyberManiac
    я не знаком с делфи
    Но думаю тс смысл понял

    число размерностью в 4 байта без учета знака
     
  7. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Похоже add eax, 1 гораздо медленнее, чем inc d,[sum] ?
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    скорее гораздо быстрее. одно обращение к памяти чего стоит. хотя потом конечно кеш подключится, но все таки с регистром быстрее работать.
     
  9. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    lilongue
    ИМХО дело в инструкции loop. Компилятор Дельфи (и Билдера тоже) при создании циклов этой инструкцией не пользуется.
    ЗЫ
    Кстати, как замерялось время? И, надеюсь, не под дебуггером?
     
  10. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    компилятор Delphi соптимизировал до
    Код (Text):
    1. sum:= 1000000000;
    2. i:= 0;
    P.S. есть же ассемблерная отладка в Delphi, какой там код?
     
  11. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Mikl__
    ЛОЛ. Нечестная оптимизация. :) Распараллеливать вычисления таким образом в данном случае еще более-менее, но вот в конце делать add между полученными суммами нечестно по отношению к Delphi.
    Можно тогда сразу как t00x предложил:
    Код (Text):
    1. mov ecx,1000000000 ;а ля начальные условия
    2.  
    3. mov [sum],ecx
    4. xor ecx,ecx
    5. mov [i],ecx
    И это будет также честно, как Ваше распраллеливание.
     
  12. zoool

    zoool New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2007
    Сообщения:
    412
     
  13. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    ИМХО с такой оптимизацией код Delphi будет быстрее, надо вместо
    Код (Text):
    1.   mov [sum], eax
    2.   add [sum],ebx
    3.   add [sum],esi
    4.   add [sum],edi
    написать
    Код (Text):
    1.   add eax,ebx
    2.   add edi,esi
    3.   add eax,edi
    4.   mov [sum], eax
     
  14. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Производительность -- это очень хитрая вещь. Например, на неё серьёзнейшее влияние оказывает то, попадают или нет код и данные в кэш-линейнки. Довольно хорошо об этом Крис Касперски писал в своей книжке про оптимизацию. Хотя речь там шла о древних (с нынешней точки зрения) процессорах, сами принципы остались в силе.

    Что же касается Дельфи, то качество кода, генерируемого транслятором, откровенно отстойное, но обычно особой роли это не играет. Если же где-то производительность действительно становится важной -- вот там и надо думать о ручной оптимизации.
     
  15. Atlantic

    Atlantic Member

    Публикаций:
    0
    Регистрация:
    22 июн 2005
    Сообщения:
    322
    Адрес:
    Швеция
    lilongue
    Ну посмотри под отладчиком, что там сделал Delphi, а потом уже это оптимизируй. Хотя у меня обычно сразу получается написать критические участки на асме лучше, чем это делает компилятор. Но времени на это уходит раз в 10 больше...

    P.S. В 10 раз по сравнению с написанием того же кода на ЯВУ, а не с компиляцией :lol:
     
  16. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    t00x
    Да ладно... не будет. Чаще всего куски кода, находящиеся за пределами циклов на возраст вселенной итераций, вообще не имеет смысла оптимизировать. И как будто у Вас вариант честнее получился. :)
     
  17. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    А что повашему такое кэш команд? Сказочка? Я не проверял, но как по мне принцапы изменились.
     
  18. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    l_inc
    имеет, когда дальнейшая развёртка цикла становится не эффективной :).

    P.S.
    относительно какого кода?
     
  19. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    t00x
    Относительно кода Mikl__.
    В данном случае для сравнения важно, чтобы количество итераций было одинаковым, а не сам результат вычислений (ИМХО не самая лучшая задача для сравнения производительностей кодов), т.к. результат вычислений заранее известен. А Вы и Mikl__ приводите код, направленный на нахождение результата. Ну так чем тогда хуже вариант
    Код (Text):
    1. mov [sum],1000000000
    2. mov [i],0
    ?
     
  20. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    TЕдинственная книжка его которая мне приглянулась %)
    Имеешь ввиду кэш трасс? Про кэш комманд в книге афаир тоже было.