· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ZEN —› Адресации и скорость

Посл.отвђт Сообщенiе


Дата: Ноя 15, 2004 00:07:54

Есть следующее задание: сравнить скорости различных адресаций (прямая, косвенная, регистровая и т.д.)
В связи с этим возникают следующие вопросы:
1) Речь идет о 15 адресациях, хотя во всех источниках описано лишь 8.
2) Как можно замерять скорость выполнения команд? rdtsc? Каждый раз выдает новый результат...
3) Совсем глупый вопрос: адресация с масштабированием.
Есть такоей пример: mov ax,[esi*2]+2
Nasm выдает invalid effective address.
Tasm компилит, но не знает о rdtsc ( invalid instruction)

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


Дата: Ноя 15, 2004 00:36:47

Помоему точные замеры сделать не поучится, лучше лит-ру на эту тему порыть


Дата: Ноя 15, 2004 04:49:14

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

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

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


Дата: Ноя 15, 2004 05:05:34

какой кэш cpuidом? кэш сбрасывается привилегерованой инструкцией [w]binvd
меряй длину цикла из 1000 итераций. очень точно выходит.могу дать прогу которая меряет латентность доступа в кэши.(чтение запись).


Дата: Ноя 16, 2004 06:59:13

Как обстоит дело с intel VTune не знаю, а вот AMD CodeAnalyst показывает время выполнения инструкций прикольными разноцветными квадратиками ;-)


Дата: Ноя 16, 2004 14:17:31

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


Дата: Ноя 16, 2004 15:17:32

Неспроста же упомянутые проги используют симуляцию + драйвер !!
Какой-там rdtsc :-(
Если речь идёт о блоке команд, то можно измерить приблизительно,
поищи по форуму profiler Maveric'а он довольно точным считается.
Одну команду IMHO нельзя никак замерить, задание те не корректное дали.
Лучше посмотреть табличку в конце мануалов по процам :-)


Дата: Ноя 16, 2004 20:51:14

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

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

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


Дата: Ноя 16, 2004 23:44:01

Проблема не в том, что надо просто сравнить, а в том что при одном и томже способе адресации могут получаться совершенно разные значения. Многое зависит от кэша, выравнивания и других неочевидных факторов. Сами цифирки ничего не дадут.


Дата: Ноя 17, 2004 03:41:25 · Поправил: S_T_A_S_

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

Или вот такая теория:
athlon способен выполнить 3 команды movreg32,mreg32 за такт.
Т.о. 1000 таких команд будет выполнено за 1000/3 = 333.3 такта.
Теперь вычисляем „скорости одной команды“: 333.3/1000 = 0.33 такта.
Однако, документация говорит, что время выполнения команды = 1 такт.
И это самый простой пример :-)


alek_sys > „что насчет 15 видов адресации?“

Возможно, речь идёт о различных вариантах кодирования:
8B 06                  mov     eax, [esi]
8B 46 00               mov     eax, [esi]
8B 86 00 00 00 00      mov     eax, [esi]
8B 04 35 00 00 00 00   mov     eax, [esi]
8B 04 26               mov     eax, [esi]
8B 84 26 00 00 00 00   mov     eax, [esi]
8B 44 26 00            mov     eax, [esi]


Дата: Ноя 17, 2004 10:19:05 · Поправил: leo

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:
port0,store:          |-mov1-|-mov2-|-mov3-|..........|-movN-|
port3,address: |-adr1-|-adr2-|-adr3-|-adr4-|...|-adrN-|
port0-port2:   |xxxхxx|хххххх|... любые другие операции из trace cache (3 моп/такт)
В итоге по сравнению с однотактовым mov имеем разницу в 1 такт хоть для 100, хоть для 1000 повторений.
Чтобы разница была заметной нужно "заставить" инструкции выполняться последовательно. Для арифметических операций это возможно, а вот для mov врядли, т.к. в соответствии с приведенной диаграммой параллельно с mov могут выполняться любые арифметические операции. Это при условии, что все мопы уже в trace кэше. Если нет то будем иметь большие непредсказуемые задержки связанные с загрузкой кода (и данных) из памяти - это ответ на вопрос "rdtsc? Каждый раз выдает новый результат..."
Чтобы не быть голословным приведу результаты своих тестов на P4-1800 (Family 15, Model 2, Stepping 7):
macro adr_test0{;контрольный тест для исключения add ecx
  repeat 128
    add ecx,4
  end repeat}  
macro adr_test1{;регистровая
  repeat 128
    mov [edi],ecx
    add edi,4
  end repeat}  
macro adr_test2{;регистр+непосредственное смещение (без SIB)
  repeat 128
    mov [edi+(%-1)*4],ecx ;в FASM выражение (%-1)*4 будет давать непосредственное смещение 0,4,8...
    add ecx,4
  end repeat}  
macro adr_test3{;SIB: база+индекс
  repeat 128
    mov [edi+ecx],edx
    add ecx,4
  end repeat}  
macro adr_test4{;SIB: база+индекс+масштаб
  repeat 128
    mov [edi+ecx*4],edx
    add ecx,1
  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.


Дата: Ноя 17, 2004 11:56:47 · Поправил: leo

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


Дата: Ноя 17, 2004 12:45:28

Всё намного проще :)
- TASM + 16 битный код;)
- 15 видов адресации (?);)
- навеянная 286 теория о влиянии способа адресации на время выполнения;)
- от самой программы не будет никакой практической пользы;)
===========================================================
Злобный профессор мучает студентов !!!

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


Дата: Ноя 17, 2004 13:43:18 · Поправил: leo

А действительно, может и "сравнивать" нужно на 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 видах адресации" лучше у него спросить - может какое открытие сделал, а "общественность" не в курсе...


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.081