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

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

  1. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    n0name Да, его самого Trace Cache.

    Если честно его книжку не читал. Сейчас проижал составленна, она по его старым записям, которые мной изучены. Собственно поэтому в ней и расматриваются старые процессоры. Новые в скользь. Чето не нашел там упоминания о Trace Cache. Где?

    Надо будет посмотреть многоли новых перлов в его книжке. Старые так точно есть.
     
  2. t00x

    t00x New Member

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

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    t00x
    Я ж и говорю, что задача не самая удачная для сравнения быстродействия кодов, т.к. результат вычислений заранее известен, и оптимизация всего кода сводится к двум mov'ам. Поэтому вариант с распределением вычислений и последующим суммированием add'ом либо нечестен либо, извиняюсь, глуп.
     
  4. zoool

    zoool New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2007
    Сообщения:
    412
    l_inc
    Тогда задача о 8ми ферзях = самый хороший тест на быстродействие.
    Напишите алогос на делфи, потом на асме. И тестите сколько влезет.
     
  5. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    очень по-дельфийски ;)
     
  6. lilongue

    lilongue New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2008
    Сообщения:
    2
    Спасибо за обсуждение. Пример действительно был не самый удачный, но это первое, что пришло в голову.
    Mikl__
    Главный и единственный косяк был действительно в loop. При замене на cmp ecx, 0; jnz a или test ecx, ecx; jnle a скорость, как минимум сравнивается с делфийским кодом (средний выигрыш 5-10 мсек при cmp ecx, 0; jnz a и inc / dec вместо add/sub хотя присутствует статистический разброс).
    Не думал, что loop работает в 4(!) раза медленнее.
     
  7. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    lilongue
    Отхожу от праведного гнева l_inc ;) но я хотел показать немного другое -
    1) начиная с Пентиума в CPU не одно АЛУ, а как минимум два - поэтому при распараллеливании скорость вычисления должна увеличиваться,
    2) количество сравнений счетчика цикла с предельным значением при включении в тело цикла двух и более иттераций уменьшается - это также приводит к увеличению скорости выполнения
    3) измерение времени выполнения при помощи "dat1, dat2 : TDateTime dat1 := now;" слишком грубое -- посмотри в поиске на wasm.ru как замеряется время и какие подводные камни при этом появятся
    4) я не знаю какие приемы для увеличения скорости использует компилятор Дельфи, но об этом можно судить только дизассемблировав твой фрагмент
    5) dec ecx/cmp ecx,0/jnz label эквивалентно dec ecx/jnz label
    6) вместо dec X/inc X, чтобы не было зависимости от флагов - лучше использовать sub X,1/add X,1
    7) читай Агнера Фога, и все что выложено сайте в разделе Статьи->Оптимизация
     
  8. n0name

    n0name New Member

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

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    trace cache - это вообще-то конкретная реализация кеша команд в NetBurst. Отличается тем, что хранит не сами данные, а декодированные микрооперации во внутреннем формате процессора. В остальных процессорах используется "классический" I-Cache.

    вообще-то для циклов с большим количеством проходов это тоже особого значения не имеет. Тело цикла осядет в кеше первого уровня уже после первого прохода, а учитывая предиктивное кеширование - еще и до него. Аналогично, предсказатель ветвлений промахнется в худшем случае максимум два раза - на первом проходе и на последнем. (на самом деле может быть и больше, но это уже экзотика)
     
  10. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    это само собой, я говорил про содержании книги.
     
  11. ksacvet777

    ksacvet777 Александр

    Публикаций:
    0
    Регистрация:
    9 ноя 2006
    Сообщения:
    180
    Адрес:
    Кемеровская обл.
    так же не забываем про директивы компилятору
     
  12. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    Я конечно понимаю, что позновато, и не представляю как это может быть, но! При мощности моего компьютера
    Код (Text):
    1. procedure TForm1.Button1Click(Sender: TObject);
    2. var
    3.   i : integer;
    4.   sum : integer;
    5.   dat1, dat2:TSystemTime;
    6. begin
    7.   GetSystemTime(dat1);
    8.   i := 1000000000;
    9.   sum := 0;
    10.   while (i > 0) do
    11.   begin
    12.     sum := sum + 1;
    13.     i := i - 1;
    14.   end;
    15.   GetSystemTime(dat2);
    16.   Caption:=inttostr(sum)+' '+inttostr((dat2.wSecond-dat1.wSecond)*1000+dat2.wMilliseconds-dat1.wMilliseconds);
    17. end;
    18.  
    19. procedure TForm1.Button2Click(Sender: TObject);
    20. label a;
    21. var
    22.   i : integer;
    23.   sum : integer;
    24.   dat1, dat2:TSystemTime;
    25. begin
    26.   GetSystemTime(dat1);
    27.   i := 1000000000;
    28.   sum := 0;
    29.   asm
    30.     mov eax, i
    31.     mov ecx, sum
    32.   a:
    33.     inc ecx
    34.     dec eax
    35.     jnz a
    36.     mov sum, ecx
    37.     mov i, eax
    38.   end;
    39.   GetSystemTime(dat2);
    40.   Caption:=inttostr(sum)+' '+inttostr((dat2.wSecond-dat1.wSecond)*1000+dat2.wMilliseconds-dat1.wMilliseconds);
    41. end;
    эти две процедуры выдают одинаковые результаты по времени. и даже не 4 сек, а меньше одной. Не знаю зачем начинали эту тему! В следующий раз стоит получше убедиться в правильности алгоритма. К тому же в исходном алгоритме не считалась сумма т.к. значение этой переменной ни где не использовалось и делфи его исключала.
     
  13. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    О несчастные, ну кто ж так пишет на Delphi?! На Delphi надо писать правильно, то есть использовать цикл FOR и встроенную функцию Inc вместо sum:=sum+1.
     
  14. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    Главное не как написать, а что получилось. А делфи и сама догадалась, что надо inc поставить. а for тут будет не уместен. его компилятор разворачивает в while c одной переменной и нарушает условие теста
     
  15. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    ну тогда надо было делать label--goto, чож вы нарушаете условия теста? ))
    да и к тому же - не забывайте про оптимизацию,
    асм то никто оптимизировать не станет, а вот делфикод..

    и почему ТС не юзал дебаггер? даже встроеный! ф4 на строке и ф2 кажется - цпу, и смотри се наздоровье как скомпилено =\
    бегиннерс =\\
     
  16. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    Так вот именно что goto будет равносильно jmp, а тогда зачем лишние делфивские нагромождения, тем более та часть только на асм, а goto из другой оперы. Вот код. Они равносильны. Не верите - ставьти Delphi и проверяйте.
     
  17. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    Какие то простенькие алгоритмы тут тестили (add, inc, loop). С такими простыми алго сам делфи нормально справляется.
    Лучший пример использования asm вставок - вычисление MD5. В инете можно легко найти этот алго на чистом паскале. Есть и с использованием asm вставок, который на порядок быстрее (в 3-4 раза, точне не помню).

    Недавно блочный TEA переписал (паскаль -> asm). Быстродействие сильно не увеличилось, т.к. там мало что оптимизировать удалось.
     
  18. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Ассемблер не для того, чтобы на нем все подряд писать. Он для реализации сложных вещей проще, чем на ЯВУ в случаях оправданности - тот же MD5. Писать на асме код как в примере ТС совершенно бесмысленно, т.к. ни особого решения не применяется, ни по скорости тут оптимизировать толком нечего.

    Я писал в свое время AES-128 на асме (MASM32) под ring0. Там было где оптимизировать, но все-равно по большей части код легко бы можно было реализовать и на C/С++ и на так многими нелюбимой Delphi.

    И может закрыть эту ветку, как вновь потенциально флудерскую.