Сайт Андрея Зайчикова
|
|
Практическое использование команд MMX для оптимизации программДмитрий Сазонов
В не таком уж далеком 1996 году корпорация Intel внедрила в свои процессоры новую мультимедийную технологию под названием MMX (MultiMedia eXtension) - которая давала (со слов фирмы) 400-процентный выигрыш в скорости работы с графикой, звуком и т.п.
Прошло время... Появились уже более новые и эффективные разработки(3D-Now, SSE), а MMX так и не получила особой популярности из-за малой документированности;все, что мне удалось найти в Internet - это немного примеров на страничке самой Intel, плюс очень небольшое количество других сайтов… в общем, негусто. В данной статье я хотел бы устранить этот пробел и рассказать вам о широчайших возможностях применения и использования MMX команд. Итак... Технология MMX состоит из 57-ми совершенно новых инструкций процессора (специально для обработки графики и звука), а также восьми универсальных 64-битных регистров (mm0-mm7). И самое главное - добавлено четыре новых 64-разрядных типа данных: Сначала хотелось бы кратко рассмотреть все эти команды (более подробное описание можно найти практически в любом современном справочнике по ассемблеру): 1)Команды пересылки данных - обмен данными между: MMX регистрами, стандартными 32-битными регистрами, а также ячейками памяти. (Movd, Movq) 2)Команды преобразования типов - конверсия из одного типа данных MMX в другой (Packss, Packus, Punpckh, Punpckl) 3)Арифметические операции - универсальные команды сложения, вычитания, умножения упакованных типов данных; как с насыщением (т.е при переполнении остается максимальное или минимальное значение), так и без него. (Padd, Padds, Paddus, Psub, Psubs, Psubus, Pmulhw, Pmullw, Pmaddwd) 4)Команды сравнения - сравнивают элементы данных (байты, слова, двойные слова) с последующим созданием маски результата. (Pcmpeq, Pcmpgt) 5)Логические операции - обычные команды логики, за исключением, что работают с 64-битной точностью (Pxor, Por, Pand, Pandn). 6)Команды сдвига - аналог стандартных команд сдвига, только эти предназначены специально для работы с упакованными типами данных. (Psll, Psrl, Psra). 7)Обнуление FPU регистров (Emms) - обязательно должно стоять после всех MMX процедур, т.к регистры mm0-mm7 заодно являются мантиссой регистров математического сопроцессора (st0-st7). А теперь - вперед! Применим все это на практике! Примечание: все процедуры, описанные здесь, основаны на 32-(24-)-битных RGB-режимах графики. 1. Для первого примера возьмем реализацию быстрого вывода картинки (спрайта) с наложением - байты изображения складываются с уже имеющимися байтами на экране (источники освещения[lensflares], частицы [particles], различные многослойные эффекты и т.д.): Сразу очевиден огромный прирост в скорости из-за параллельной обработки сразу четырех байт, а также из-за отсутствия команд условных переходов. Кстати - при использовании Psubusb (с константой) вместо Paddusb можно получить супер-быстрый RGB-фильтр, что тоже весьма приятно. 2. Еще один пример вывода картинки (спрайтов): на этот раз с прозрачностью - вывод на экран только тех байт, чьи значения не равны константе прозрачности (этот метод используется практически во всех современных 2D-играх). Как и в первом примере, получаем немалое ускорение - за счет отсутствия команд условных переходов, а также из-за параллельности обработки сразу нескольких байт изображения. 3. Размытие при движении (motion blur) – объекты оставляют за собой плавно угасающий шлейф (применяется и на телевидении, и в 3D играх). Сразу восемь байт! То самое 400% ускорение, которое нам так долго рекламировала Intel. 4. Канал прозрачности (alpha blending) [далее ab] – одно изображение плавно появляется или растворяется поверх другого (также очень часто применяется при работе с видео). Формула ab:a = b + (a - b) * alpha Где: a – основное изображение переведем это все в MMX-команды: a) инициализация регистров биты31...2423...1615...8 7...0 movd mm4,eax; переносим данных из eax в mm4 б) основная процедура В данном примере используется быстрое 16-битное MMX-умножение, которое и дает максимальное ускорение нашей процедуре. Плюс - уже ставшая традицией – обработка сразу четырех байт... Ну вот; в приведенных примерах мы рассмотрели практически все MMX-команды и способы ММХ-оптимизации - применяя их. Осталось заметить: чтобы получить еще более быстродействующие программы, нужно размещать команды согласно правилам оптимизации под соответствующий процессор (к сожалению, у Intel и AMD они разные), а также правильно использовать его внутренний кэш. Большую часть этой работы берут на себя компиляторы высокого уровня (C++, Pascal, Basic и т.д.), но ассемблерные вставки придется переделывать вручную… На чем хотелось бы и закончить. Используйте MMX в своих программах! |