...
...

3DNow! технология

3DNow! технология

Окончание. Начало в N№ 30

AMD-K6-2 содержит новый конвейеризированный функциональный узел для выполнения операций над числами в формате с плавающей запятой, реализующий технологию 3DNow!. 3DNow! содержит 21 дополнительную команду, новые типы данных и регистры для поддержки высокопроизводительной обработки 3D графики и звука. Повышение скорости вычислений с плавающей запятой осуществляется за счет параллельного (одновременного) исполнения нескольких операций, а также ряде быстрых команд вещественной арифметики (деление, обратное значение квадратного корня). При этом используется техника векторных команд - SIMD (Single Instruction, Multiple Data - одиночный поток команд, множественный поток данных). Векторные команды выполняют одну операцию над несколькими парами операндов одновременно. Векторный параллелизм в достаточной степени (ускорение порядка нескольких десятков раз и более) находится в мультимедийных и научных алгоритмах. Векторные команды 3DNow! параллельно обрабатывают две пары 32-битных вещественных операндов одинарной точности, в то время как скалярные команды 3DNow! работают лишь с одной парой 32-битных операндов (из младших частей 64-битных операндов).

Технология 3DNow! использует упакованный формат данных. Два вещественных числа упаковываются в один 64-битный MMX/3DNow! регистр или 64-битную ячейку памяти. Формат вещественных чисел одинарной точности, используемый в 3DNow! технологии, совместим с форматом вещественных чисел одинарного формата IEEE-754, включающий 1 знаковый бит, 8 бит смещенной экспоненты и 23-битную мантиссу числа с одним спрятанным битом (в итоге 24 бита точности). На рисунке ниже представлен упакованный вещественный тип данных технологии 3DNow!, в который входят два вещественных числа одинарной точности (старшие 32 бита D0 и младшие 32 бита D1).

D 0 (63..32) D 1 (31..0)
Процессор AMD-K6-2 содержит восемь 64-битных MMX/3DNow! регистров. Как показано на рисунке ниже, 3DNow! и MMX обращаются к данным регистрам, используя мнемонику mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7. Эти регистры используют общую аппаратуру со стандартными x87 регистрами для чисел с плавающей запятой двойной точности. Такой подход к отображению 3DNow! регистров на стек регистров x87 позволяет сохранить совместимость аппаратуры с существующим программным обеспечением (если бы для этих регистров использовалась отдельная аппаратура, то потребовалось бы добавить код в ОС для сохранении новых MMX/3DNow! регистров при переключении задач).

mm0 D0 (63..32) D1 (31..0)
mm1 D0 (63..32) D1 (31..0)
mm2 D0 (63..32) D1 (31..0)
mm3 D0 (63..32) D1 (31..0)
mm4 D0 (63..32) D1 (31..0)
mm5 D0 (63..32) D1 (31..0)
mm6 D0 (63..32) D1 (31..0)
mm7 D0 (63..32) D1 (31..0)
Процессор AMD-K6-2 может выполнять две 3DNow! команды за такт и, следовательно, 4 операции над числами с плавающей запятой одновременно. Технология 3DNow! предлагает для выполнения векторных MMX и 3DNow! операций несколько устройств (пара умножителей, сумматоров и т.д.). Все команды 3DNow! имеют длительность исполнения 2 такта и полностью конвейеризированы.

Оптимизированный 3DNow! код представляет собой спланированные команды 3DNow! с учетом доступных вычислительных ресурсов, времени исполнения команд и существующих зависимостей по данным в программе. Для удобства проведения оптимизации при программировании операции 3DNow! объединены в две группы, формирование которых основывалось на объеме и природе доступных вычислительных ресурсов. Если две смежные 3DNow! команды находятся в разных группах, то они могут начинать исполнение одновременно без задержек. Первая группа 3DNow! команд: PFADD, PFSUB, PFSUBR, PFACC, PFCMPx, PFMIN, PFMAX, PI2FD, PF2ID, PFRCP и PFRSQRT; вторая: PFMUL, PFRCPIT1, PFRSQIT1 и PFRCPIT2.

Команды 3DNow!

Технология 3DNow! предоставляет программисту команды, которые поддерживают векторные операции над числами с плавающей запятой, целочисленными данными (PAVGUSB, PMULHRW), а также предвыборку данных (PREFETCH) и быстрое переключение между MMX и вычислениями с плавающей запятой (FEMMS). Для улучшения декодирования MPEG в расширение набора команд включена специальная команда PAVGUSB для упрощения расчета компенсации движения пикселов (pixel-motion compensation). Из-за того, что media-приложения оперируют большими наборами данных, процессор вынужден часто обращаться в оперативную память. От нежелательных простоев, вызванных задержками обращения в память (отсутствием данных в КЭШ), позволяет избавиться команда PREFETCH. Ее функционирование сводится к проверке наличия данных в КЭШе первого уровня L1. Для обеспечения быстрого переключения между кодом MMX и FPU (x87) предлагается использовать 3DNow! команду FEMMS, которая быстрее, чем EMMS. Специальное переключение между MMX и 3DNow! не требуется, и, следовательно, возможна одновременная или совместная обработка как целочисленных (MMX), так и вещественных (3DNow!) данных.

Формат команд 3DNow! :

3DNow!mnemonic mmreg1, mmreg2/mem64

Операнд-приемник должен быть MMX регистром (mm0-mm7). Операнд-источник может быть как MMX регистром (mm0-mm7), так и операндом в памяти. Используемые сокращения в мнемонике команд: P - Packed (упакованный), F - Float (вещественный), I - Integer (целочисленный).

Команды вещественной арифметики

PF2ID mmreg1, mmreg2/mem64

Векторная PF2ID команда преобразует два упакованных вещественных операнда из mmreg2/mem64 в упакованные 32-битные целые значения в регистр mmreg1, усекая результат при необходимости.

PFACC mmreg1, mmreg2/mem64

Векторная операция PFACC складывает два вещественных числа из операнда-приемника mmreg1 и записывает результат в младшие 32 бита mmreg1, а также складывает два вещественных числа операнда-источника mmreg2/mem64 и записывает результат в старшие 32 бита mmreg1.

mmreg1[31:0] = mmreg1[31:0] + mmreg1[63:32]
mmreg1[63:32] = mmreg2/mem64[31:0] + mmreg2/mem64[63:32]

PFADD mmreg1, mmreg2/mem64

Векторная операция PFADD выполняет сложение упакованных вещественных чисел операнда-источника mmreg2/mem64 и операнда-приемника mmreg1.

mmreg1[31:0] = mmreg1[31:0] + mmreg2/mem64[31:0]
mmreg1[63:32] = mmreg1[63:32] + mmreg2/mem64[63:32]

PFCMPEQ mmreg1, mmreg2/mem64

Векторная операция PFCMPEQ выполняет сравнение пар упакованных вещественных чисел операнда-источника и операнда-приемника и генерирует все единицы, если соответствующие пары равны, или все нули, если пары не равны.

IF (mmreg1[31:0] = mmreg2/mem64[31:0])
THEN mmreg1[31:0] = FFFF_FFFFh
ELSE mmreg1[31:0] = 0000_0000h
IF (mmreg1[63:32] = mmreg2/mem64[63:32]
THEN mmreg1[63:32] = FFFF_FFFFh
ELSE mmreg1[63:32] = 0000_0000h

PFCMPGE mmreg1, mmreg2/mem64

Векторная операция PFCMPGE выполняет сравнение пар упакованных вещественных чисел операнда-источника и операнда-приемника и генерирует все единицы, если вещественное число в mmreg1 больше или равно соответствующему числу в mmreg2/mem64, или все нули в противном случае.

IF (mmreg1[31:0] >= mmreg2/mem64[31:0])
THEN mmreg1[31:0] = FFFF_FFFFh
ELSE mmreg1[31:0] = 0000_0000h
IF (mmreg1[63:32] >= mmreg2/mem64[63:32]
THEN mmreg1[63:32] = FFFF_FFFFh
ELSE mmreg1[63:32] = 0000_0000h

PFCMPGT mmreg1, mmreg2/mem64

Векторная операция PFCMPGT выполняет сравнение пар упакованных вещественных чисел операнда-источника и операнда-приемника и генерирует все единицы, если вещественное число в mmreg1 больше соответствующего числа в mmreg2/mem64, или все нули в противном случае.

IF (mmreg1[31:0] > mmreg2/mem64[31:0])
THEN mmreg1[31:0] = FFFF_FFFFh
ELSE mmreg1[31:0] = 0000_0000h
IF (mmreg1[63:32] > mmreg2/mem64[63:32]
THEN mmreg1[63:32] = FFFF_FFFFh
ELSE mmreg1[63:32] = 0000_0000h

PFMAX mmreg1, mmreg2/mem64

Векторная операция PFMAX возвращает большее из двух упакованных вещественных чисел. Если один операнд меньше нуля, а второй равен нулю, то результат равен +0. Если два операнда равны нулю, будет возвращен +0.

IF (mmreg1[31:0] > mmreg2/mem64[31:0])
THEN mmreg1[31:0] = mmreg1[31:0]
ELSE mmreg1[31:0] = mmreg2/mem64[31:0]
IF (mmreg1[63:32] > mmreg2/mem64[63:32])
THEN mmreg1[63:32] = mmreg1[63:32]
ELSE mmreg1[63:32] = mmreg2/mem64[63:32]

PFMIN mmreg1, mmreg2/mem64

Векторная операция PFMIN возвращает меньшее из двух упакованных вещественных чисел. Если один операнд равен нулю, а второй - положительное число, то результатом будет +0. Если оба операнда равны нулю, то результат будет +0.

IF (mmreg1[31:0]
THEN mmreg1[31:0] = mmreg1[31:0]
ELSE mmreg1[31:0] = mmreg2/mem64[31:0]
IF (mmreg1[63:32]
THEN mmreg1[63:32] = mmreg1[63:32]
ELSE mmreg1[63:32] = mmreg2/mem64[63:32]

PFMUL mmreg1, mmreg2/mem64

Векторная команда PFMUL выполняет умножение упакованных вещественных чисел.

mmreg1[31:0] = mmreg1[31:0] * mmreg2/mem64[31:0]
mmreg1[63:32] = mmreg1[63:32] * mmreg2/mem64[63:32]

PFRCP mmreg1, mmreg2/mem64

Скалярная команда PFRCP возвращает приближенное значение обратной величины операнда-источника mmreg2/mem64. Результат дублируется в старшей и младшей частях операнда-приемника mmreg1. Исходный операнд является вещественным числом одинарной точности (24 бита мантисса), а точность результата достигает 14 бит.

mmreg1[31:0] = reciprocal(mmreg2/mem64[31:0])
mmreg1[63:32] = reciprocal(mmreg2/mem64[31:0])

Для получения более точного результата (24 значащих бита мантиссы вещественного числа одинарной точности) требуется использовать дополнительные команды (PFRCPIT1 и PFRCPIT2).

PFRCPIT1 mmreg1, mmreg2/mem64

Векторная команда PFRCPIT1 выполняет первый шаг в итерации метода Ньютона-Рафсона для уточнения обратной величины, полученной в PFRCP (второй и последний шаг доводит точность результата до 24 бит). Корректное функционирование этой команды требует использования в качестве одного операнда входного значения команды PFRCP, а другого операнда - результата той же команды PFRCP.

PFRCPIT2 mmreg1, mmreg2/mem64

Векторная команда PFRCPIT1 выполняет второй и последний шаг в итерации метода Ньютона-Рафсона для уточнения обратной величины или обратного значения квадратного корня, полученных в командах PFRCP и PFSQRT соответственно. Для корректного функционирования данной команды требуется использовать в качестве операнда-источника mmreg2/mem64 результат команды PFRCP или PFSQRT, а операндом-приемником mmreg1 выступает результат операции PFRCPIT1 или PFRSQIT1.

PFRSQIT1 mmreg1, mmreg2/mem64

Векторная операция PFRSQIT1 выполняет первый шаг в итерации метода Ньютона-Рафсона для уточнения приближения обратного значения квадратного корня, полученного в команде PFSQRT (второй и последний шаг уточняет значение до 24 значимых бит). Для корректного функционирования данной команды следует использовать в качестве одного операнда входное значение команды PFRSQRT, а в качестве другого - результат команды PFRSQRT.

PFRSQRT mmreg1, mmreg2/mem64

Скалярная команда PFRSQRT возвращает приближенное значение обратного значения квадратного корня вещественной величины операнда-источника mmreg2/mem64. Результат операции дублируется в старшей и младшей частях 64-битного регистра mmreg1. Точность результата достигает 15 бит. Отрицательный операнд рассматривается как положительный для корректного вычисления квадратного корня. Знак результата устанавливается таким же, как и у операнда-источника. Для достижения точности в 24 бита мантиссы вещественного числа требуется выполнить еще две команды (PFRSQIT1 и PFRCPIT2).

mmreg1[31:0] = reciprocal square root(mmreg2/mem64[31:0])
mmreg1[63:32] = reciprocal square root(mmreg2/mem64[31:0])

PFSUB mmreg1, mmreg2/mem64

Векторная команда PFSUB выполняет вычитание упакованных вещественных чисел операнда-источника mmreg2/mem64 из вещественных чисел операнда-приемника mmreg1.

mmreg1[31:0] = mmreg1[31:0] - mmreg2/mem64[31:0]
mmreg1[63:32] = mmreg1[63:32] - mmreg2/mem64[63:32]

PFSUBR mmreg1, mmreg2/mem64

Векторная команда PFSUBR выполняет вычитание упакованных вещественных чисел операнда-приемника mmreg1 из упакованных вещественных чисел операнда-источника mmreg2/mem64.

mmreg1[31:0] = mmreg2/mem64[31:0] - mmreg1[31:0]
mmreg1[63:32] = mmreg2/mem64[63:32] - mmreg1[63:32]

PI2FD mmreg1, mmreg2/mem64

Векторная команда PI2FD преобразует упакованные целые 32-битные знаковые числа в упакованные вещественные числа одинарной точности, усекая при необходимости результат.

mmreg1[31:0] = float(mmreg2/mem64[31:0])
mmreg1[63:32] = float(mmreg2/mem64[63:32])

Дополнительные команды

PAVGUSB mmreg1, mmreg2/mem64

Векторная команда PAVGUSB выполняет усреднение с округлением восьми беззнаковых целочисленных пар байт mmreg2/mem64 и mmreg1. Для этого байты операндов складываются, затем к 9-битному промежуточному значению добавляется 01h. После этого промежуточное значение делится на два, и затем восемь беззнаковых байт результата записываются в MMX регистр mmreg1.

Команда PAVGUSB может использоваться для усреднения пикселов в операциях видео-масштабирования и компенсации движения в алгоритмах MPEG-2.

mmreg1[63:56] = (mmreg1[63:56] + mmreg2/mem64[63:56] + 01h)/2
mmreg1[55:48] = (mmreg1[55:48] + mmreg2/mem64[55:48] + 01h)/2
mmreg1[47:40] = (mmreg1[47:40] + mmreg2/mem64[47:40] + 01h)/2
mmreg1[39:32] = (mmreg1[39:32] + mmreg2/mem64[39:32] + 01h)/2
mmreg1[31:24] = (mmreg1[31:24] + mmreg2/mem64[31:24] + 01h)/2
mmreg1[23:16] = (mmreg1[23:16] + mmreg2/mem64[23:16] + 01h)/2
mmreg1[15:8] = (mmreg1[15:8] + mmreg2/mem64[15:8] + 01h)/2
mmreg1[7:0] = (mmreg1[7:0] + mmreg2/mem64[7:0] + 01h)/2

PMULHRW mmreg1, mmreg2/mem64

Векторная команда PMULHRW умножает четыре целых знаковых 16-битных значения операнда mmreg2/mem64 на четыре соответствующих знаковых 16-битных числа в операнде mmreg1. Команда PMULHRW затем добавляет 8000h к младшим 16 битам 32-битного результата, что равнозначно округлению старших 16 цифр результата. Затем старшие 16 бит результата (включая знаковый бит) сохраняются в операнде приемнике mmreg1. Команда PMULHRW возвращает более точный результат, чем команда PMULHW, которая просто усекает результат, вместо его округления.

PREFETCH/PREFETCHW mem8

Операция загружает строку КЭШа данных, адрес которой указывается в операнде mem8. Для процессора AMD-K6-2 размер строки КЭШа равен 32 байтам. Во всех последующих процессорах размер будет как минимум 32 байта. Если происходит попадание в КЭШе (строка уже находится в КЭШе данных) или обнаруживается ошибка памяти, цикл шины не инициируется и команда рассматривается как NOP.

Данная команда может быть эффективно использована при обработке больших наборов данных. При этом PREFETCH может осуществлять предварительную подгруздку данных в КЭШ первого уровня L1, в то время как процессор будет обрабатывать текущую порцию данных. После завершения обработки текущего блока данных, следующая порция уже будет находится в КЭШе первого уровня, и таким образом удастся избежать временных затрат на обращения в ОЗУ. Это позволяет программисту явно программировать поступление потока данных, подстраивая его под поток команд. Примером такой параллельной обработки, использующей данную команду, может являться просчет вершин треугольников при 3D преобразованиях, где, в то время как текущий набор вершин участвует в вычислениях (поворот, смещение), следующий набор выбирается из ОЗУ в КЭШ данных L1.

Подгружаемой строке КЭШа команда PREFETCHW присваивает атрибут modified (MESI state), в то время как команда PREFETCH обычно устанавливает этот атрибут в exclusive. Если данные, загружаемые в КЭШ данных, предполагается изменять, использование команды PREFETCHW позволяет сэкономить такт, который требуется команде PREFETCH для изменения атрибута строки КЭШа данных.

FEMMS

Как и в EMMS, команду FEMMS можно и должно использовать в конце блока MMX команд для сброса MMX состояния. Это необходимо делать, так как MMX регистры разделяют общую аппаратуру с модулем плавающей запятой процессора. В отличие от команды EMMS после команды FEMMS содержимое регистров остается неопределенным. Таким образом, FEMMS предоставляет более быстрое контекстное переключение в конце MMX подпрограммы, в случае если значения регистров MMX более не требуются.

Таблица 1. 3DNow!(tm) команды

Команда Функционирование
PAVGUSB Упакованное побайтное целочисленное усреднение
PFADD Упакованное вещественное сложение
PFSUB Упакованное вещественное вычитание
PFSUBR Упакованное вещественное обратное вычитание
PFACC Упакованное вещественное сложение с накоплением
PFCMPGE Упакованное вещественное сравнение. >=
PFCMPGT Упакованное вещественное сравнение. >
PFCMPEQ Упакованное вещественное сравнение. =
PFMIN Упакованный вещественный минимум
PFMAX Упакованный вещественный максимум
PI2FD Преобразование 32-битных целых в вещественные числа
PF2ID Преобразование вещественных чисел в 32-битные целые числа
PFRCP Приближенное обратное значение
PFRSQRT Приближенное обратное значение квадратного корня
PFMUL Упакованное вещественное умножение
PFRCPIT1 Первый шаг нахождения обратного значения
PFRSQIT1 Первый шаг нахождения обратного значения квадратного корня
PFRCPIT2 Второй шаг нахождения обратного значения или обратного значения квадратного корня
PMULHRW Упакованное умножение целочисленных слов с округлением
FEMMS Быстрая смена MMX состояния и FPU x87
PREFETCH Предвыборка как минимум 32 байт в КЭШ данных L1

К сожалению, команда MADD (умножение с последующим сложением вещественных чисел), активно использующаяся при геометрических вычислениях в 3D конвейере, и команда MAC (умножение с накопление), присутствующая во многих DSP, не вошли в расширение команд процессора AMD-K6-2. Появление подобных инструкций в последующих моделях МП от AMD могло бы существенно повысить скорость вычислений, задействованных в 3D-визуализации.

Вычисление обратной величиныи квадратного корня

3DNow! команды могут использоваться для быстрого вычисления с высокой точностью обратного значения вещественного числа. Рассмотрим отношение q=a/b. При помощи таблицы ROM, расположенной на кристалле, осуществляется приблизительная оценка значения обратной величины 1/b с точностью 14-15 знаков мантиссы (команда PFRCP). Используя полученное приближенное значение, 24 бита точности можно получить в первой же итерации алгоритма Ньютона-Рафсона.

Рекуррентное соотношение данного алгоритма следующее:

X i+1=X i(2-bX i)

Используя в качестве X 0 приближенное значение с точностью 14 бит, на первой же итерации алгоритма мы получаем требуемую точность в 24 бита. Для вычисления отношения следует воспользоваться следующим кодом:

(точность 14 бит)

MOVD MM0, [mem] ; 0 | w
PFRCP MM0, MM0 ; 1/w | 1/w (approx.)
MOVQ MM2, [mem] ; y | x
PFMUL MM2, MM0 ; y/w | x/w

(точность 24 бита)

MOVD MM0, [mem] ; 0 | w
PFRCP MM1, MM0 ; 1/w | 1/w (approx.)
PFRPIT1 MM0, MM1 ; 1/w | 1/w (intermed.)
MOVQ MM2, [mem] ; y | x
PFRCPIT2 MM0, MM1 ; 1/w | 1/w (full prec.)
PFMUL MM2, MM0 ; y/w | x/w

Вычисление квадратного корня вещественного числа также может быть существенно ускорено при помощи команд 3DNow!. Рекуррентная формула алгоритма Ньютона-Рафсона в данном случае будет следующей:

X i+1=1/2X i(3-bX 2 i)

Для уменьшения числа итераций X0 выбирается из таблицы ROM командой PFRSQRT (точность 15 бит). Для достижения точности в 24 бита при вычислении квадратного корня следует воспользоваться следующим кодом:

(точность 15 бит)

MOVD MM0, [mem] ; 0 | a
PFRSQRT MM1, MM0 ; 1/(sqrt a) | 1/(sqrt a) (approx.)
PFMUL MM0, MM1 ; (sqrt a) | (sqrt a)

(точность 24 бита)

MOVD MM0, [mem] ; 0 | a
PFRSQRT MM1, MM0 ; 1/(sqrt a) | 1/(sqrt a) (approx.)
MOVQ MM2, MM1 ; 1/(sqrt a) | 1/(sqrt a) (approx.)
PFMUL MM1, MM1 ; (sqrt a) | (sqrt a) step 1
PFRSQIT1 MM1, MM0 ; (sqrt) (intermed.) step 2
PFRCPIT2 MM1, MM2 ; (sqrt) (full prec.) step 3
PFMUL MM0, MM1 ; (sqrt a) | (sqrt a)

Материал основан на информации от корпорации Advanced Micro Devices ( http://www.amd.com ), исследованиях Hardware Guide ( http://www.hardware.pairnet.com ), The 3DNow! Now page ( http://ren.tierranet.com/3dnow/ ), Hardware TechSupport ( http://ixbt.stack.net ).


Андрей Терешко
E-mail: atere@usa.net


- титульная страница


© Компьютерная газета

полезные ссылки
Оффшорные банковские счета