Адресации и скорость

Тема в разделе "WASM.A&O", создана пользователем alek_sys, 15 ноя 2004.

  1. alek_sys

    alek_sys New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2004
    Сообщения:
    7
    Адрес:
    Russia
    Есть следующее задание: сравнить скорости различных адресаций (прямая, косвенная, регистровая и т.д.)

    В связи с этим возникают следующие вопросы:

    1) Речь идет о 15 адресациях, хотя во всех источниках описано лишь 8.

    2) Как можно замерять скорость выполнения команд? rdtsc? Каждый раз выдает новый результат...

    3) Совсем глупый вопрос: адресация с масштабированием.

    Есть такоей пример: mov ax,[esi*2]+2

    Nasm выдает invalid effective address.

    Tasm компилит, но не знает о rdtsc ( invalid instruction)



    Буду рад любой подсказке...
     
  2. Turkish

    Turkish New Member

    Публикаций:
    0
    Регистрация:
    25 окт 2004
    Сообщения:
    80
    Адрес:
    Russia
    Помоему точные замеры сделать не поучится, лучше лит-ру на эту тему порыть
     
  3. Johnikum

    Johnikum Member

    Публикаций:
    0
    Регистрация:
    6 июн 2003
    Сообщения:
    97
    а так:

    db 0Fh,031h ; rdtsc

    mov ax,[esi*2+2] ;(хотя NASM не видел) или тоже опкодами



    А перед rdtsc (первой) сбросить кэш, например командой CPUID, и замерять не один раз, а 1000 или больше, и брать средний результат. А вообще на форуме измерение скорости уже не раз обсуждалось.



    P.S. Админам: из ОПЕРЫ сообщения не отправляются, или это у меня только так мудит :dntknw:(
     
  4. Narkomanius

    Narkomanius New Member

    Публикаций:
    0
    Регистрация:
    14 апр 2003
    Сообщения:
    144
    какой кэш cpuidом? кэш сбрасывается привилегерованой инструкцией [w]binvd

    меряй длину цикла из 1000 итераций. очень точно выходит.могу дать прогу которая меряет латентность доступа в кэши.(чтение запись).
     
  5. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Как обстоит дело с intel VTune не знаю, а вот AMD CodeAnalyst показывает время выполнения инструкций прикольными разноцветными квадратиками :derisive:
     
  6. alek_sys

    alek_sys New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2004
    Сообщения:
    7
    Адрес:
    Russia
    Нужно написать программу, которая измеряла бы скорости выполнения инструкций, а не использовать intel VTune, AMD CodeAnalyst и т.д.

    В принципе, db 0Fh,031h в TASME прокатило, я думаю, дальше разберусь. Хотя остается вопрос о количестве адресаций. Пятнадцати я что-то не насчитал - в реальном режиме по крайней мере, а гонять проц из режима в режим... Вообще завал...
     
  7. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Неспроста же упомянутые проги используют симуляцию + драйвер !!

    Какой-там rdtsc :-(

    Если речь идёт о блоке команд, то можно измерить приблизительно,

    поищи по форуму profiler Maveric'а он довольно точным считается.

    Одну команду IMHO нельзя никак замерить, задание те не корректное дали.

    Лучше посмотреть табличку в конце мануалов по процам :)
     
  8. alek_sys

    alek_sys New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2004
    Сообщения:
    7
    Адрес:
    Russia
    А если забацать 1000 (например) mov ax,[ds:si] а потом рез-т делить на 1000 для скорости одной команды? Сразу другой вопрос - как боротся с оптимизацией? Ведь 1000-у mov'ов компилятор превратит в 1?



    И, кстати, задание звучит так : "...сравнить скорости различных адресаций...", так что особая точность не требуется, лишь бы было видно разницу!



    И все-таки, что насчет 15 видов адресации?
     
  9. Turkish

    Turkish New Member

    Публикаций:
    0
    Регистрация:
    25 окт 2004
    Сообщения:
    80
    Адрес:
    Russia
    Проблема не в том, что надо просто сравнить, а в том что при одном и томже способе адресации могут получаться совершенно разные значения. Многое зависит от кэша, выравнивания и других неочевидных факторов. Сами цифирки ничего не дадут.
     
  10. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Совершенно верно!

    И ещё: когда измеряем цикл, команды организации цикла тоже что-то весят.

    Если же просто расположить подряд 1000 mov ax,[ds:si], то начнёт сказаваться время предвыборки в кэш.



    Или вот такая теория:

    athlon способен выполнить 3 команды movreg32,mreg32 за такт.

    Т.о. 1000 таких команд будет выполнено за 1000/3 = 333.3 такта.

    Теперь вычисляем
    : 333.3/1000 = 0.33 такта.

    Однако, документация говорит, что время выполнения команды = 1 такт.

    И это самый простой пример :)





    alek_sys >




    Возможно, речь идёт о различных вариантах кодирования:

    <font face="monospace]
    Код (Text):
    1.  
    2. 8B 06                  mov     eax, [esi]
    3. 8B 46 00               mov     eax, [esi]
    4. 8B 86 00 00 00 00      mov     eax, [esi]
    5. 8B 04 35 00 00 00 00   mov     eax, [esi]
    6. 8B 04 26               mov     eax, [esi]
    7. 8B 84 26 00 00 00 00   mov     eax, [esi]
    8. 8B 44 26 00            mov     eax, [esi]
    </font><!--face-->
     
  11. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    alek_sys



    Чем наивнее вопрос, тем сложнее на него дать ответ в двух словах. Самое простое - это отправить к "праотцам" учить домашнее задание. Если удосужиться заглянуть в руководство уважаемого Агнера Фога "How to optimize for the Pentium microprocessors" http://www.agner.org/assem/pentopt.pdf, то можно найти там массу интересного. В частности, получить ответ как правильно использовать RDTSC для тестирования и ссылочку на архивчик заготовок тестовых программ http://www.agner.org/assem/testp.zip. Посмотришь на таблички instruction timings и поймешь, что для PII,PIII,P4 mov r,m это 1 микрооперация независимо от вида адресации. С mov m,r похитрее: на PII,PIII это 2 моп независимо от вида адресации, а на P4 - 1 моп без использования байта SIB и 2 моп с использованием. Хотя - это не официальные данные и возможно на P4 тоже никакой разницы нет.

    Допустим, что есть, но тогда вопрос: а можно ли на практике заметить эту разницу. В данном случае 2 моп - это вычисление адреса + собственно mov операнда из регистра в буфер записи. Выполняются они на разных исполнительных блоках и через разные порты, а следовательно могут параллелиться с предыдущими и последующими командами. Умозрительно берем один mov m,r и имеем два такта |-adr-|-mov-|. Теперь берем 1000 последовательных mov m,r и в идеале имеем примерно такую диаграмму для P4:
    Код (Text):
    1. port0,store:          |-mov1-|-mov2-|-mov3-|..........|-movN-|
    2. port3,address: |-adr1-|-adr2-|-adr3-|-adr4-|...|-adrN-|
    3. port0-port2:   |xxxхxx|хххххх|... любые другие операции из trace cache (3 моп/такт)
    В итоге по сравнению с однотактовым mov имеем разницу в 1 такт хоть для 100, хоть для 1000 повторений.

    Чтобы разница была заметной нужно "заставить" инструкции выполняться последовательно. Для арифметических операций это возможно, а вот для mov врядли, т.к. в соответствии с приведенной диаграммой параллельно с mov могут выполняться любые арифметические операции. Это при условии, что все мопы уже в trace кэше. Если нет то будем иметь большие непредсказуемые задержки связанные с загрузкой кода (и данных) из памяти - это ответ на вопрос "rdtsc? Каждый раз выдает новый результат..."

    Чтобы не быть голословным приведу результаты своих тестов на P4-1800 (Family 15, Model 2, Stepping 7):
    Код (Text):
    1. macro adr_test0{;контрольный тест для исключения add ecx
    2.   repeat 128
    3.     add ecx,4
    4.   end repeat}  
    5. macro adr_test1{;регистровая
    6.   repeat 128
    7.     mov [edi],ecx
    8.     add edi,4
    9.   end repeat}  
    10. macro adr_test2{;регистр+непосредственное смещение (без SIB)
    11.   repeat 128
    12.     mov [edi+(%-1)*4],ecx ;в FASM выражение (%-1)*4 будет давать непосредственное смещение 0,4,8...
    13.     add ecx,4
    14.   end repeat}  
    15. macro adr_test3{;SIB: база+индекс
    16.   repeat 128
    17.     mov [edi+ecx],edx
    18.     add ecx,4
    19.   end repeat}  
    20. macro adr_test4{;SIB: база+индекс+масштаб
    21.   repeat 128
    22.     mov [edi+ecx*4],edx
    23.     add ecx,1
    24.   end repeat}
    Для всех вариантов получились результаты ОДИН В ОДИН: разница по числу тиков с контрольным тестом равна ровно 128 тактов (292 против 164 - это с вместе с overhead-пустышкой для устранения зависимости от RDTSC). Т.е. имеем, что в потоке команд mov m32,r32 занимает 2 такта вместе с add r32,imm32 независимо от рассмотренных способов адресации. Ну и сколько же приходится на одну инструкцию - 2 такта или 1 ?



    PS: Тестировал на модифицированном варианте теста от Gray http://wasm.ru/forum/files/975894600__test.asm Суть модификации в изменении overhead-пустышки. Оказывается bogrus "подсунул" :) нам вариант теста Агнера для P\PMMX c оверхедом в виде 8 нопов, а на PIII, P4 это не полностью устраняет влияние RDTSC. Нужно все-таки использовать CPUID или достаточно длинную цепочку арифметических операций (штук 16-32), чтобы тестовый кусок не начинался до завершения RDTSC.
     
  12. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Turkish & S_T_A_S_

    > "Многое зависит от кэша, выравнивания и других неочевидных факторов"

    Полностью согласен. По незнанию и неопытности можно получить ложные зависимости и сделать неверные выводы. Похоже, что данная задачка либо 1) просто наивно-некорректная, 2) просто элементарная "на засыпку" или 3) супер-сложная исследовательская задача, требующая знания всех тонкостей архитектуры и посильная разве, что доктору Фогу и другим "светилам".
     
  13. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Всё намного проще :)

    - TASM + 16 битный код;)

    - 15 видов адресации (?);)

    - навеянная 286 теория о влиянии способа адресации на время выполнения;)

    - от самой программы не будет никакой практической пользы;)

    ===========================================================

    Злобный профессор мучает студентов !!!



    ЗЫ всё IMHO конечно =)
     
  14. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    А действительно, может и "сравнивать" нужно на 286-486 ?!



    Кстати это тоже вопрос - на чем. На P4 возможно все проще, а вот на PII\PIII можно столкнуться с интересными эффектами. Поясню мысль. Разумные устойчивые цифры с RDTSC можно получить только на 3-4м проходе, когда данные и код уже кэшированы. Но тогда на P4 "рулит" trace-кэш с макимальным темпом выборки 3 мопа за такт и предвыборка кода сказывается слабо. Тут есть только опасность перегрузить trace-кэш, поэтому о развернутых репитах на несколько тысяч лучше сразу забыть. А вот на PII\PIII инструкции декодируются на лету блоками по 16 байт. Здесь для развернутой последовательности мувов можно столкнуться с тормозами на предвыборку и декодирование инструкций, причем могут получиться разные результаты в зависимости от длины инструкции. Например, для одной и той же адресации mov eax,[esi+imm] имеем три байта при imm < 128 и шесть байт если >= 128. В первом случае будем иметь 5 инструкций на выборку, во втором только 2 -> процессору чаще придется обращаться к кэшу за новым блоком (а времени-то мало, если мувы выполняются достаточно быстро). Не исключено, что может получиться ситуация когда короткий цикл из одного мува будет работать быстрее, чем развернутый (если все тело цикла меньше 16 байт).



    Да что там говорить... Наверное у профессора в голове все проще. И о "15 видах адресации" лучше у него спросить - может какое открытие сделал, а "общественность" не в курсе...
     
  15. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    leo




    Да, было дело :) У Агнера (в .chm) там оверхед нужно вручную подставлять для своего камня, а я прикрутил его автоматический подсчет, но кроме селеронов Mendocino, Coppermine и Tualatin я ничего не имею, по-этому есть затруднения с P4.

    Сейчас переделал его консольный wtest.asm на фасм с мессаджбоксом (в аттаче), там нужно протестить его на разных процах, правильно ли считает оверхед.

    Просто запустите wintest.exe, если будут не нули, то сообщите результат и камень плиз.

    И второе, если все ок с оверхедом, то раскомментируйте запись "mov eax,[mem]", запустите (F9 в фасме) и тоже сообщите о результате, у меня он такой:
    Код (Text):
    1. ---------------------------
    2. 5 bytes , 10 passes
    3. ---------------------------
    4. 000000000000000000310252
    5. 000000000000000000000000
    6. 000000000000000000000000
    7. 000000000000000000000000
    8. 000000000000000000000000
    9. 000000000000000000000000
    10. 000000000000000000000000
    11. 000000000000000000000000
    12. 000000000000000000000000
    13. 000000000000000000000000
    14. ---------------------------
    15. OK
    16. ---------------------------
    С первым проходом понятно, mem находится в отдельной секции, к ней никто не обращался и этих данные нет ни в каком кеше, возможно вообще в ОЗУ (?), по-этому много тактов, но это правильный результат, а у Агнера в wtest.asm, если следовать его совету (; put any data here that your test code needs), то свои данные мы размещаем в общей с "техническими" данными секции, к которой уже были обращения, по-этому они уже в кеше "не по нашей вине" и соотв. получаем "ускоренный" результат.



    Меня интересуют остальные проходы, по-идее "mov eax,[mem]" должна отбирать 1 такт (т.к. на втором проходе mem уже в кеш-ряде L1), но у меня (Celeron Coppermine-128 666MHz) тест показывает 0, а при двух таких инструкциях показывает 1 такт. Как правильно то? (xочу настроить тестовую программу)



    [​IMG] _1431307943__wintest.zip
     
  16. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    bogrus

    256

    остальные 28, камень P-4 2.4B(533)
     
  17. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Это результат пустого теста или "mov eax,[mem]"?
     
  18. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    bogrus

    просто стартанул ехе

    еще вариации первых чисел 28 ; 244 ; 292 ; 316 ; 302 (все остальные по 28)

    В основном 244(60%)



    Могу разогнать проц до 2,8 или если постараться то до 3,0
     
  19. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Блин, значит неправильно считает оверхэд на 28 тактов для P4

    да нет, не стоит :)
     
  20. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    bogrus

    могу ещё проверить на пентиуме 900 на нотебуке(точно камень не помню но могу глянуть), ещё на атлоне 1700+ и возможно ещё нескольких. Проверять? но это тока на завтра