
MMX-технология
С точки зрения программиста MMX-технология — это самое значительное нововведение в линии процессоров x86 со времени появления 386-го процессора.
MMX предоставляет программисту новые встроенные типы данных и набор инструкций для работы с ними. Для MMX использован принцип SIMD (Single Instruction — Multiple Data). Одной инструкцией можно параллельно обработать несколько единиц информации. За этот счет уменьшается время обработки информации. Это особенно важно для мультимедийных систем, когда наборы байтов подвергаются последовательности однотипных операций. Отсюда и название MMX — MultiMedia eXtension — мультимедийное расширение..
Если набор инструкций MMX включен в процессор Pentium, то процессор называют Pentium MMX. Если в Pentium Pro (т.е. P6), то процессор получает название Pentium II.
Новые типы данных
Вводится четыре типа данных. Каждый имеет размер 64 бита. Перечислим их.
Упакованные байты (Packed bytes)
63 |
|
|
|
|
|
|
0 |
|
|
|
|
|
|
|
|
Упакованные слова (Packed words)
63 |
|
|
0 |
|
|
|
|
Упакованные двойные слова (Packed doublewords)
63 |
0 |
|
|
Учетверенное слово (QuadWord)
63 |
0 |
|
|
Любую из этих структур данных можно загрузить в MMX-регистр и выполнить операцию параллельной обработки компонент.
Регистры mmx
Для MMX новых регистров в процессор встраивать не стали, а воспользовались уже знакомым нам набором восьми регистров FPU. MMX-регистры отображены на поле мантиссы регистров FPU. В поле порядка при работе с MMX-инструкциями автоматически помещаются единицы.
79 |
63 |
0 |
1111111111111111 |
mm0 |
|
… |
… |
|
1111111111111111 |
mm7 |
|
Имя регистра указывает на физический номер регистра, независимо от содержимого поля ST. После выполнения команды MMX в регистр тегов записываются нули. Смешивать команды MMX и команды плавающей арифметики не рекомендуется. После выполнения серии MMX-команд нужно выполнить команду emms. Эта команда занесет в теги всех регистров значение 11, т.е. пометит все регистры FPU как пустые.
Арифметика с насыщением.
Мы знаем, что если в байте содержится число 255, то прибавление к нему 1 даст в байте нуль. (При этом CF = 1.) Такая арифметика носит название "арифметика с циклическим переносом" (wraparound arithmetic).
В MMX имеется возможность наряду с привычной нам арифметикой использовать так называемую "арифметику с насыщением" (saturation arithmetic). Если результат арифметической операции превышает предельное значение, то он полагается равным этому предельному значению: 255 + 1 = 255. Это бывает полезным в алгоритмах обработки изображений. Конечно, несложно запрограммировать арифметику с насыщением с помощью уже известных команд, но наличие встроенных команд, реализующих "насыщение", может существенно ускорит работу алгоритмов.
Пример программы
Дано два восьмибайтных массива. Сложить их элементы как знаковые, с насыщением. Поместить результат в третий массив.
При написании этой программы проблема заключается в том, что TASM не распознает инструкций MMX. Поэтому придется программировать в кодах.
.MODEL small
.STACK 100h
.DATA
vec1 DB 120,120,–120,–120,0,0,0,0
vec2 DB 10,2,–10,–2,0,0,0,0
vec3 DB 8 DUP(0)
.CODE
start: mov ax,@data
mov ds,ax
; movq mm0,vec1 ; переслать учетверенное слово в mm0
DB 0Fh,6Fh,06h,00h,00h
; paddsb mm0,vec2 ; Сложить с насыщением упакованные байты
; Мнемоника: p – packed, add — сложение, s – saturation, b – bytes
DB 0Fh,0ECh,06h,08h,00h
; movq vec3,mm0 ; переслать учетверенное слово в vec3
DB 0Fh,7Fh,06h,10h,00h
; emms
DB 0fh,77h
mov ax,4C00h
int 21h
END start
Поясним кодировку команд на примере команды paddsb mm0,vec2. Код операции, занимающий два байта: 0Fh,0ECh, взят из справочника[]. Следующий байт представим в двоичной форме: 06h = 00 000 110b. Поля mod = 00 и r/m = 110 соответствуют прямой адресации. Поле reg = 000 кодирует регистр mm0. В коде команды 0ECh зашифровано, что именно регистр является приемником. 08h, 00h — это смещение (displacement), равное 0008h для vec2. Его можно было взять из листинга, но и так нетрудно догадаться о его значении.
Транслируем и компонуем программу обычным образом программами tasm и tlink. Выполним программу под управлением td. Расположим на экране одно под другим окна CPU и Numeric Processor. Проследим выполнение программы по шагам.
После выполнения команды movq mm0,vec1 в окне Numeric processor увидим
Spec ST(0) –NAN FFFF 0000 0000 8888 7878
Поле порядка заполнено единицами. С точки зрения FPU в регистре записано "не число" (Not a Number), поэтому оно помечено как специальное. В поле мантиссы мы видим упакованные компоненты массива vec1. При этом 78h = 120, 88h = –120.
После выполнения команды paddsb mm0,vec2:
Spec ST(0) –NAN FFFF 0000 0000 8680 7A7F
После команды emms:
Empty ST(0) –NAN FFFF 0000 0000 8680 7A7F
Содержимое то же самое, но теперь регистр помечен как пустой.
В панели данных читаем содержимое v3:
7F 7A 80 86 00 00 00 00, т.е. 127, 122, –128, –122, 0, 0, 0, 0.
Мы видим эффект сложения "с насыщением". При этом 8 байтов обработаны одной командой.
Конечно, интересно было бы фиксировать, для каких слагаемых насыщение сработало, а для каких нет. Но специальных регистров флагов для упакованных байтов нет. Команды MMX регистр флагов не изменяет.
Задача. Написать программу, которая реализует те же действия, но с использованием команд процессора 8086, 80386.