Member
Статус: Не в сети Регистрация: 28.02.2005 Откуда: Брянск
Глава 1. Немного теории из какого-то Intel Optimization Guide...
Вот посмотрите.
Время исполнения некоторых инструкций.
0F3n - (0F34 - это Пресскот, у меня типа),
0F2n - это видимо Нортвуд (потому что немного быстрее)
069n - это Pentium M (вообше странно - как у него могут быть такие огромные скорости, помоему мобильные скоростью не блещут, или я как всегда не прав?)
Инструкция 0F3n / 0F2n / 069n
Если написано только два числа - значит там нет ничего про 069n (не особо он нам нужен).
Что означает запись типа 18+17 я не знаю.
Деление с SSE (с каким SSE не посмотрел - ленивый)
Single(32 бита)
DIVPS xmm,xmm 40 / 39 / 18+17
DIVSS xmm,xmm 32 / 23
(Тут выходит что 4 операции деления выполняются всего за 40 тактов, что в принципе очень даже быстро)
Double(64 бита)
DIVPD xmm,xmm 70 / 69 / 32+31
DIVSD xmm,xmm 39 / 38 / 32
Умножение с SSE (аналогично)
Double
MULPD xmm, xmm 7 / 6
MULSD xmm, xmm 7 / 6
(А тут выходит 4 умножения(деления) со скоростью света)
Single
MULPS xmm, xmm 7 / 6 / 4+1
MULSS xmm, xmm 7 / 6
И всё остальное с любимым FPU
FADD 6 / 5 и FSUB 6 / 5 - это просто так.
FMUL 8 / 7
FDIV Single Precision (я понимаю тут 32бита) 30 / 23
FDIV Double Precision (а тут аж 64) 40 / 38
FDIV Extended Precision (и наконец все положенные 80) 44 / 43
(А тут одно деление, но скока тактов отнимает)
И обычным ALU
IMUL r32 10 / 14 / 4
IMUL imm32 "почему-то ничего не написано" / 14 / 4
IMUL "почему-то ничего не написано" / 15-18 / 4
IDIV 66-80 / 56-70
MUL 10 / 14-18
DIV 66-80 / 56-70
"почему-то ничего не написано" - почему-то не написали но числа по идее поменьше чем у норта, т.к. в скоте чёта с MUL'ями подкрутили(это я типа похвалил свой любимый пресскот, а то как не гляну в профиль сплошные атлоны).
Глава 2. Тепер "Нафига он это все напечатал?".
Данная таблица (почти таблица) показывает что лучше умножать нежели делить, причем во всех случаях начинаяя с FPU и заканчиваяя SSE. Возникает вопрос "А каким ... умножить, если надо разделить?!".
Отвечаю: Например как поделить на два. Деление на два можно заменить умножением на 0.5, аналогично деление на 4 заменяем умножением на 0.25. Вот даже формулу изобрел:
с=a/b менеяем на с=a*(1/b). Конечно в коде такое не надо писать, надо просто заменить все /b , на заранее посчитанные *1/b. Ну вы в общем меня поняли. В любом случае умножение на FPU быстрее деления на ALU!!! Вся эта петиция писалась относительно Пентиумов4 (но на Атлонах с их быстрющими FPU тоже наверное будет работать). Кстати про замену деления умножением я где-то прочитал (в нэте), а где не помню. Потом вспомнил - этому же в школе учили (кто не помнит (я недавно из школы улетел) это переворачивание дроби при делении дроби на дробь(переворачиваем делитель и меняем деление на умножение))!!!
Так что если много деления - можно получить солидный SpeedUp, а главное - никакого ассемблера, тока С или Паскаль.
И ВОТ САМОЕ ГЛАВНОЕ умножение и деление в SSE выполняются на РАЗНЫХ блоках, значит можно сразу множить и делить через умножение(или умножать)!!! _serj А насчет NOP'ов ты прав, частично, но все равно пустоту для выравнивания надо чем-то забить. А может можно там NOP'ов натыкать и JMP перед ними (правда толку с этого), но все равно перед таким циклом это мелочи. И вот ещё: Интел в коде тоже пишет xor eax,eax ;clear eax - вот так вот...(наверное есть на то причина):):):)
Advanced member
Статус: Не в сети Регистрация: 10.04.2003 Откуда: Москва
Toad, почитай оптимизацию от AMD - там очень подробно и просто 'все это' расписано.
Только не используй REP для пустого выравнивания, на Intel Р4 комбинация "REP+NOP" что-то жуткое! Номер документа 22007
Member
Статус: Не в сети Регистрация: 28.02.2005 Откуда: Брянск
serj_ На что ты намекаешь?? И линк на доки кинь плиз.
Я потом тесты провел насчет деления и умножения и просто ужаснулся. Нифига не делаешь ~120 тактов, множить или делить через SSE ~2000 тактов(8 делений), через FPU ~25000 (1 деление)!!! Не могу в этот прикол въехать.
Member
Статус: Не в сети Регистрация: 28.02.2005 Откуда: Брянск
Ща ещё хуже стало, два RDTSC занимают 25-30 тысяч тактов. Раньше получалось что миллион делений как раз за 40 тактов в среднем проскакивали с умножением какой то ужас - миллион умножений ~2 800 000 000 тактов!!!! Одно деление/умножение - дофига тактов, а если много то все по плану не считая некоторых глюков...
Member
Статус: Не в сети Регистрация: 28.02.2005 Откуда: Брянск
serj_ У меня меньше 96 за 2 RDTSC, ни разу не было (обычно ~110), еще зависит чем компилируешь + настроение компа!!! А для более менее стабильных результатов надо чтоб в начале что-то выполнилось (типа NasmW+MinGW=Стабильные результаты, FASM=Скачка от 96 до нескольких тысяч тактов). Кстати слил один с амд - очень классно там все написано. Короче с RDTSC мерить можно только большой кусок кода, а скока одна инструкция отнимает тактов - помоему бесполезно!
Advanced member
Статус: Не в сети Регистрация: 30.08.2003 Откуда: Санкт-Петербург
Toad
Цитата:
короче с RDTSC мерить можно только большой кусок кода, а скока одна инструкция отнимает тактов - помоему бесполезно
конечно она же еще и спарится с чем-нибудь, и в microop превратится (а про перестановку microop'ов/операций процом помним?), так что фиг посчитаешь...
PS: понятно, что время исполнения операции - от 0 тактов до некой максимальной величины.. (если, конечно, не брать во внимание работу с памятью/кэшем)
_________________ {:€ дед в законе :-) нородный окодемег почетный пользователь OpenSuSE 11.3 Ремонт и модернизация ноутбуков IBM (Lenovo) ThinkPad
Member
Статус: Не в сети Регистрация: 28.02.2005 Откуда: Брянск
Ну насчет перестановки, есть опреации сериализации (не знаю что это такое но они вперед себа RDTSC не пускают - это SFENCE MFENCE LFENCE и CPUID, их рекомендуюют ставить перед вторым RDTSC), но это в принципе ничего не меняет. Вот так вот VTune в зубы и мануалы и гиды читать. И все равно новый проц и все оптимизации улетучиваются (читали про XviD на ixbt.com) так что что-то сильно точить опасно .
Advanced member
Статус: Не в сети Регистрация: 30.08.2003 Откуда: Санкт-Петербург
Toad
Цитата:
А есть ли русская инструкция как пользоваться АСМом в GCC
вряд ли. Зато есть книжка Зубкова "Ассемблер для DOS, Windows и Unix", а там синтаксис AT&T описан... Проблема в том, что в GCC асм - юниксовый и в нем немного по другому сделана система команд. Например, 1) каждая команда имеет суффикс в зависимости от размера операнда b = byte w = word l = long = double word q = quad word s = single precision float (32-bit) l = double precision (long) float (64-bit) t = 80-bit float. В паскале вроде обзывался Extended.. Например: movb $0, var - переместить байт 0 в переменную var размером 1 байт movw $0, var - переместить слово 0 в переменную var размером 2 байта и т.д. 2) регистры обознаются %. Например: %eax - регистр eax 3) immediate value, т.е. непосредственное значение ("константа") обозначаются $. Например: $2 - значение 2, $200h - 200h=512 4) порядок аргументов всегда обратный интеловскому. Т.е. сначала источник, затем место назначения: movb %al, var - переместить из AL в байтовую переменную VAR movb var, %al - переместить из байтовой переменной VAR в AL и т.д.
Добавлено спустя 1 минуту, 28 секунд: Для того чтобы в СИшный код вставить ассемблерную вставку можно сделать так:
а здесь ситуация такая, что надо по адресу addr положить данные.
в общем, формат очень похож на printf:
сначала идет текст команды+модификаторы, а в конце то, что вместо них подставляется...
_________________ {:€ дед в законе :-) нородный окодемег почетный пользователь OpenSuSE 11.3 Ремонт и модернизация ноутбуков IBM (Lenovo) ThinkPad
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения