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).
Процессор AMD-K6-2 содержит восемь 64-битных MMX/3DNow! регистров. Как показано на рисунке ниже, 3DNow! и MMX обращаются к данным регистрам, используя мнемонику mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7. Эти регистры используют общую аппаратуру со стандартными x87 регистрами для чисел с плавающей запятой двойной точности. Такой подход к отображению 3DNow! регистров на стек регистров x87 позволяет сохранить совместимость аппаратуры с существующим программным обеспечением (если бы для этих регистров использовалась отдельная аппаратура, то потребовалось бы добавить код в ОС для сохранении новых MMX/3DNow! регистров при переключении задач).
Процессор 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) команды
К сожалению, команда 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
- титульная страница
Окончание. Начало в 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) |
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) |
Оптимизированный 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
- титульная страница
Компьютерная газета. Статья была опубликована в номере 31 за 1998 год в рубрике hard :: video