Введение в команды MMX.
Призрак ММХ (MultiMedia extension) уже давно бродит по страницам компьютерных изданий. И хотя этого зверя видели в действии еще не многие, шуму вокруг него предостаточно. “ММХ — прорыв в новое тысячелетие", — говорят нам страницы газет, А все почему? Из-за каких-то пятидесяти семи инструкций! И хотя цифра внушает нам трепет, все же не совсем ясно, как, не меняя кардинально архитектуру микропроцессора, можно получить супер-мультимедийный компьютер? За счет чего? Постараемся развеять туман, нагнанный рекламной компанией на простые вещи.
Существует множество multime-dia-приложений. На первый взгляд, между ними нет ничего общего. Однако на самом деле внутри все они, как близнецы-братья. Мультиме-дийные приложения обрабатывают большие объемы данных. Самая трудоемкая и в тоже время часто используемая операция — применение одного и того же преобразования к массиву данных, Как это понимать? Допустим, у нас есть два массива, А и В, длиной по 8 байтов каждый. Поставим себе задачу прибавить к каждому элементу массива В соответствующий ему элемент массива А. Это приведет нас к такой программе:
Mov |
esi, offset A |
Mov |
edi, offset В |
mov |
ecx, 8 |
OurLoop: |
|
Mov |
al, [esi] |
Add |
[edi], al |
Inc |
esi |
inc |
edi |
loop |
OurLoop |
Как видим, несмотря на простую постановку задачи, процессор будет вынужден выполнить нетривиальную последовательность команд восемь раз. Вот если бы операцию сложения двух массивов можно было выполнить одной командой... На этой идее и был построен ММХ. Аналогичная программа с его использованием имела бы такой вид:
movq |
mmregl, |
A |
movq |
mmreg2, |
В |
paddb |
mmregZ, |
mmregl |
movq |
B, mmreq2 |
Не правда ли, просто и элегантно? Какое отношение это все имеет к multimedia? Допустим, выполняется программа, обрабатывающая 256-цветное изображение. Обычно она обрабатывает каждый пиксель по отдельности. С ММХ ей доступны сразу восемь пикселей! Так что же такое ММХ? ММХ — это расширение, включающее в себя 57 новых команд и восемь 64-разрядных регистров. В основу положен принцип SIMD (Single Instruction Multiple Data: одна инструкция — множество данных). ММХ предоставляет инструкции для складывания, умножения и даже выполнения комбинированных операций. К примеру, команда PMADDWD перемножает, а затем складывает четыре слова данных, при этом она выполняется намного быстрее программы, использующей только набор “стандартных” инструкций. Технология ММХ предоставляет простую, гибкую программную модель, не требуя при этом перевода процессора в какой-то особенный режим. Все существующие программы будут корректно исполняться на процессорах с ММХ без каких-либо изменений, даже если в системе присутствуют приложения, использующие новую технологию.
Регистры
В процессоры, использующие ММХ, добавлено 8 новых 64-разрядных регистров ММО-ММ7. Они могут быть использованы только для выполнения операций с типами данных ММХ. Команды ММХ позволяют задавать в качестве операндов как регистры общего назначения (ЕАХ, ЕВХ, ECX, EDX, ЕВР, ESI,
EDI и ESP), так и переменные в памяти, используя для этого стандартную схему адресации, принятую в процессорах х86. Хотя ММХ-регистры и имеют ни с чем не совпадающие названия, на самом деле они являются “псевдонимами” регистров сопроцессора (st0-st7). Это означает, что, изменяя один из регистров ММХ в своей программе, мы в то же время изменяем регистры сопроцессора. Зачем такие сложности? Не проще ли было их сделать “раздельными”? В конце концов, для этого понадобилось бы не так уж и много усилий со стороны разработчиков процессора... Очевидно, это было сделано не только с целью добавить работы программистам. Как всегда, все дело в совместимости. Если бы было сделано так, как подсказывает логика, то пришлось бы переписать операционную систему! Те, кто знаком с работой процессора в защищенном режиме, наверное, уже догадались, о чем идет речь. Конечно же, о мультизадачности. Дело в том, что в многозадачной среде программы должны быть независимы друг от друга. При переключении с одной задачи на другую значения всех регистров “старой” задачи должны быть сохранены. В настоящее время о сохранении регистров микропроцессора заботится сам микропроцессор, а о сохранении регистров сопроцессора заботится операционная система. Так как все
регистры ММХ одновременно являют собой регистры FPU (Floating Point Unit — сопроцессор), то операционная система, сохраняя регистры FPU, сохраняет и регистры ММХ! Проблема решена, кроме того, она избавила нас от ожидания выхода Windows 95 ММХ. Программист должен заботиться о том, чтобы код, использующий FPU и ММХ, работал корректно. Код одного типа (ММХ или FPU) должен быть по возможности сгруппирован. Для достижения наибольшей производительности в программе не должно быть условных переходов из части кода, использующего FPU, к коду, использующему ММХ. После того как работа с ММХ завершена, нужно очистить регистры mmregO-mmreg7. Это делается для того, чтобы в последующем сопроцессор не столкнулся с “грязными” регистрами непонятного формата. Для этого используется новая инструкция EMMS, которая помечает все регистры FPU как “пустые”.Префиксы
Всем инструкциям х86 ставится в соответствие число - код операции. Длина кода операции один-два байта. Ему может передшествовать байт SIB (Scale-масштаб, Index-индекс, Base-база), определяющий полный режим адресации. В процессоре х86 перед инструкцией также возможно присутствие префиксов, несколько модифицирующих “смысл” команды (префикс замены сегмента, префикс команды). Инструкции ММХ формируются точно так же, как и “старые” команды.
Распаровка (paring)
Точно так же, как и “обычные” инструкции микропроцессора, инструкции MMX могут выполняться в паре с другой инструкцией одновременно. Более того, в некоторых случаях возможно одновременное выполнение двух инструкций MMX. Операции сдвига и умножения могут быть выполнены как на и-, так и на v-конвейере21. Ограничения, накладываемые на возможность распа-ровки, следующие:
• Две инструкции, использующие блок сдвигов MMX (инструкции упаковки/распаковки и сдвига), не могут выполняться одновременно.
• Две инструкции, использующие блок умножения MMX (инструкции типа pmul, pmulh, pmadd), не могут выполняться в паре.
• Целевой регистр ММХ-инструк-ции, попавшей в и-конвейер, не должен совпадать с регистром-источником инструкции, попавшей на v-конвейер (тест на зависимость). То есть пара инструкций:
paddb mmreg2, mmregl
paddb mmregЗ, mmreg2
не может выполняться одновременно,
• Инструкция EMMS не паруется.
• Если установлены CRO.TS или CRO.EM, то ММХ-инструкции не могут быть выполнены на v-конвейере.
Типы данных
MMX поддерживает данные в упакованном формате. Это означает, что каждый 64-битовый регистр MMX может интерпретироваться как:
1. Восемь байтов;
2. Четыре слова;
3. Два двойных слова;
4. Одна 64-разрядная переменная. То, как интерпретируется конкретный регистр, отлично отображается в мнемонике команды. К примеру, инструкция PADDB складывает два операнда, полагая, что они являются набором байтов, a PADDW считает операнды набором слов.
Все инструкции можно разбить на следующие группы3':
умножение |
PMULHW |
PMULLW |
вычитание |
PSUBB |
PSUBD |
|
PSUBSB |
PSUBSW |
|
PSUBUSB |
PSUBUSW |
|
PSUBW |
|
команды сравнения
проверка равенства
PCMPEQB PCMPEQD
PCMPEQW сравнение PCMPGTB PCMPGTD
PCMPGTW
команды упаковки/распаковки
PUNPCKHBW PUNPCKHDQ PUNPCKHWD PUNPCKLBW PUNPCKLDQ PUNPCKLWD PACKSSDW PACKSSWB PACKUSWB
логические команды |
|
PAND |
PANDN |
POR |
PXOR |
команды передачи данных |
|
MOVD |
MOVQ |
команда |
сдвига |
|
|
|
логический сдвиг |
влево |
|
|
PSLLD |
PSLLQ |
|
|
PSLLW |
|
|
|
|
|
арифметические команды |
|
арифметический сдвиг вправо PSRAD PSRAW |
|
сложение PADDB |
PADDD |
|
|
PADDSB PADDUSB |
PADDSW PADDUSW |
логический сдвиг вправо PSRLD PSRLQ |
|
PADDW |
|
|
|
сложение и умножение |
команды, очищавшие регистры |
||
PMADDWD |
|
EMMS |
Краткое описание команд
Приведем описание лишь некоторых инструкций, помогающих понять суть работы ММХ.
MOVD
Формат
MOVD mmregl, reg32/mem32MOVD reg32/mem32, mmregl Описание
Инструкция MOVD пересылает 32 младших бита регистра ММХ в регистр общего назначения или память Или же из регистра общего назначения/памяти в регистр ММХ В последнем случае, кроме собственно пересылки, биты 32-64 соответствующего регистра обнуляются
PADDB
Формат
PADDB mmregl, mmreg2/mem64 Описание
Складывает восемь 8-разрядных чисел операнда источника (ММХ-регистра или 64-разрядного поля памяти) и восемь 8-разрядных чисел операнда-получателя (регистра ММХ) В случае переполнения полученные значения заворачиваются (то есть 255+10=9) без установки флага переноса при подсчете последующих байтов Результат помещается в операнд-получатель
PADDSW
Формат PADDSW mmregl, mmreg2/mem64
Описание
Складывает четыре 16-битных числа со знаком операнда источника (регистра ММХ или 64-разрядного поля памяти) и четыре соответствующих значения операнда-получателя (регистра ММХ) Если сумма каких-либо двух из них менее чем -32768 (8000h), то результат сложения -32768 (8000
h) Аналогично в случае, когда сумма превышает 32767 (7FFFh), возвращаемый результат — 32767 (7FFFh) Результат заносится в операнд-получатель Следующий список возможных ситуаций помогает понять, как происходит сложениеЕсли число D250h (-11696) складывается с 88Q7h (-30713), то получаемый результат 8000h (-32768) — минимально возможное 16-разрядное число
Если число 5321h (+21281) прибавляется в ЕС22h (-5086), то получаемый результат 3F43h (+ 16195)
Сумма 16-разрядного числа7007П (+28679) и OFF9h (+4098) дает результат 7PFFh (+32767) — максимально возможное положительное число
Если к FFFFh(-1) прибавить FFFFh(-1), то получим FFFEh (-2)/
Описание:
Инструкция PAND выполняет логическую операцию “и” над операндами Результат заносится в операнд-получатель Если соответствующие биты источника и получателя равны единице, то значение итогового бита единица Эта команда может использоваться для распаковки упакованных переменных при помощи маски, полученной от инструкций сравнения PCMPEQ и PCMPGT
PCMPEQB
Формат
:PCMPEQB mmregl, mmreg2 /mem64
Описание
Сравнивает источник с получателем, рассматривая операнды как упакованные байты Если биты операндов эквивалентны, то все биты 8-разрядной части получателя устанавливаются равными единице, в противном случае они обнуляются
PCMPGTD
Формат
PCMPGTB mmregl, mmreg2/mem64
Описание
Аналогична PCMPEQ, но в отличие от нее биты в целевом операнде устанавливается в том случае, когда байт целевого операнда больше соответствующего байта операнда источника
PACKUSWB
Формат
PACKUSWB mmregl, mmreg2/mem64 Описание
Переводит восемь знаковых слов, задаваемых аргументами (по четыре слова в каждом), в восемь беззнаковых байтов После чего результат сохраняется в mmregl Сатурация при этом происходит следующим образом
• если слово содержит отрицательное число, то соответствующий ему байт будет равен нулю,
• если значение слова превышает 255, то соответствующий ему байт будет равен 255
Рис. А Команда PACKUSWB
Команды ММХ имеют такой формат:
инструкция mmreg1, mmreg2/mem64
То есть источником может быть как переменная памяти, так и регистр ММХ. А целевым может быть только регистр ММХ, К тому же MOVD и MOVQ допускают пересылки из регистров ММХ в память, Одним из первых вопросов у меня был, зачем так много команд? Ведь количество операций не так уж и велико... Дело в том, что название команды формируется из двух частей. Первая часть говорит о том, что она делает (MOV, PSUB, PADD). Вторая же говорит о том, как она интерпретирует операнды. Рассмотрим команду PACKUSWB. Первая часть строки — PACK — указывает, что будем что-то упаковывать. Вторая же — USWB — в свою очередь разбивается на две — US и WB. US говорит о том, что результат будет беззнаковым с сатурацией
4', WB же указывает, что источник — упакованные слова,результат — упакованные байты. Благодаря такой записи смысл инструкции схватывается “на лету”, по этой же причине и команд так много. Приведем полный перечень мнемоник:Р— упакованные данные
(Packed data)В— байт (byte)
W— слово (word)
D— двойное слово (DoubleWord)
Q— 64-битовая переменная (QuadWord)
S— знаковая (Signed)
U— беззнаковая (Unsigned)
SS— знаковая с сатурацией (Signed Saturation)
US—беззнаковая с сатурацией (Unsigned Saturation)
. Итак, появились процессоры с ММХ — ряд процессоров Intel—Pentium и новый процессор AMD Кб. Допустим, мы их купили, и они уже исправно на нас работают. Будут ли мульти-медийные приложения работать быстрее? Ответ — да. Благодаря новому набору команд ММХ? Ответ - нет. Дело в том, что процессор Intel-Pentium с технологией ММХ отличается от своего собрата без таковой не только набором команд, но и тем, что у него:
• вдвое больший кэш первого уровня (32Кб),
• улучшенный блок предсказания условных переходов,
• углубленный конвейер.
За счет этого производительность Pentium ММХ возросла на стандартных тестах на 10-20%. Когда же преимущества станут ощутимы в полной мере? Увы — не мгновенно. Действительно, факт появления этой технологии на свет не решает наших проблем. Нужно подождать, пока не раскачаются программисты и не напишут приложения, использующие команды, ММХ. Очевидно, что рано или поздно это произойдет. Вопрос только,когда.
Вообще существует множество задач, где ММХ приходится весьма кстати. К примеру, ММХ прекрасно подходит для задач обработки звука, Действительно, оцифрованный звук задается последовательностью 8-, 16- или 32-разрядных чисел. По этой причине, если нам нужно, к примеру, воспроизвести два звука одновременно, то согласно теореме о суперпозиции нам следует сложить соответствующие последовательности чисел. Тут ММХ на высоте. Кроме того, как нельзя кстати приходится возможность складывать с са-
турацией. В результате скорость может быть повышена в 4-5 раз.
Однако разрядность ММХ-регис-тров, к сожалению, мала. Поэтому некоторые классы задач сложно приспособить к использованию этой мощи. К примеру, в графике часто нужно выполнить операцию умножения матрицы на матрицу или вектора на матрицу. Казалось бы, вот где ММХ понадобится. Однако в большинстве задач в качестве элементов матрицы или вектора используются числа с плавающей точкой. Вывод — ММХ тут не применишь. Правда, можно в качестве элементов использовать числа с фиксированной точкой1. Размер такого числа — четыре байта. То есть в один регистр поместится только два элемента вектора. Тонкость тут в том, что в случае трехмерных преобразований скалярное произведение нужно считать от двух трехэлементных векторов... Решить проблему можно — использовать для этого два ММХ-регист-ра: в первом — два элемента, во втором — один. Однако выигрыш при этом будет не столь значителен, как хотелось бы.
К чему же мы пришли? Очевидно, что технология ММХ — это шаг вперед. Аббревиатура ММХ уже стала символом революции. Недаром корпорация Intel пыталась в судебном порядке запретить ее использовать AMD (впрочем, безуспешно). ММХ-технология прекрасно вписывается в существующую архитектуру микропроцессора. Сохраняется полная совместимость с уже написанными программными продуктами. Хотя наряду с этим видны и ограничения, заложенные в нее, которые со временем нужно будет преодолевать.