SSE
SSE(англ.Streaming SIMD Extensions,потоковое SIMD-расширение процессора) — этоSIMD- (англ.Single Instruction, Multiple Data,Одна инструкция — множество данных) набор инструкций, разработанныйIntelи впервые представленный в процессорах серииPentium IIIкак ответ на аналогичный набор инструкций3DNow!отAMD,который был представлен годом раньше. Первоначально названием этих инструкций было KNI —Katmai New Instructions(Katmai — название первой версии ядра процессораPentium III).
ТехнологияSSEпозволяла преодолеть две основные проблемыMMX:при использовании MMX невозможно было одновременно использовать инструкциисопроцессора,так как его регистры были общими с регистрами MMX, и возможность MMX работать только с целыми числами.
SSE включает в архитектуру процессора восемь 128-битныхрегистрови набор инструкций, работающих со скалярными и упакованными типами данных.
Преимущество в производительности достигается в том случае, когда необходимо произвести одну и ту же последовательность действий над разными данными. В таком случае блоком SSE осуществляется распараллеливание вычислительного процесса между данными.
Особенности
[править|править код]- 8 (вx86-64— 16) 128-битных регистров XMM.
- 32-битный (в x86-64 — 64)регистр флагов(MXCSR).
- 128-битный упакованный тип данных с плавающей точкойодинарной точности.
- Инструкции над вещественными числами одинарной точности.
- Инструкции явной предвыборки данных, контролякэшированияданных и контроля порядка операций сохранения.
Регистры
[править|править код]В SSE добавлены восемь (шестнадцать для x64) 128-битных регистров, которые называются xmm0 — xmm7 (-xmm15).
Каждый регистр может содержать четыре 32-битных значения с плавающей запятой одинарной точности.
SSE-команды
[править|править код]Команды для чисел с плавающей точкой
- Команды пересылки
- Скалярные типы — MOVSS
- Упакованные типы — MOVAPS, MOVUPS, MOVLPS, MOVHPS, MOVLHPS, MOVHLPS
- Арифметические команды
- Скалярные типы — ADDSS, SUBSS, MULSS, DIVSS, RCPSS, SQRTSS, MAXSS, MINSS, RSQRTSS
- Упакованные типы — ADDPS, SUBPS, MULPS, DIVPS, RCPPS, SQRTPS, MAXPS, MINPS, RSQRTPS
- Команды сравнения
- Скалярные типы — CMPSS, COMISS, UCOMISS
- Упакованные типы — CMPPS
- Перемешивание и распаковка
- Упакованные типы — SHUFPS, UNPCKHPS, UNPCKLPS
- Команды для преобразования типов
- Скалярные типы — CVTSI2SS, CVTSS2SI, CVTTSS2SI
- Упакованные типы — CVTPI2PS, CVTPS2PI, CVTTPS2PI
- Битовые логические операции
- Упакованные типы — ANDPS, ORPS, XORPS, ANDNPS
Команды для целых чисел
- Арифметические команды
- PMULHUW, PSADBW, PAVGB, PAVGW, PMAXUB, PMINUB, PMAXSW, PMINSW
- Команды пересылки
- PEXTRW, PINSRW
- Другие
- PMOVMSKB, PSHUFW
Другие команды
- Работа с регистром MXCSR
- LDMXCSR, STMXCSR
- Управлениекэшеми памятью
- MOVNTQ, MOVNTPS, MASKMOVQ, PREFETCH0, PREFETCH1, PREFETCH2, PREFETCHNTA, SFENCE
Пример
[править|править код]Следующий пример демонстрирует перемножение четырёх пар чисел с плавающей точкой одной инструкциейmulps: (Программа написана на языке ANSI C++ с использованиемассемблернойвставки __asm и инструкций ассемблера для работы с SSE, аргументы записаны согласно стандарту Intel, а не AT&T)
__declspec(align(16))floata[4]={300.0,4.0,4.0,12.0};
__declspec(align(16))floatb[4]={1.5,2.5,3.5,4.5};
__asm{
movupsxmm0,a;// поместить 4 переменные с плавающей точкой из a в регистр xmm0
movupsxmm1,b;// поместить 4 переменные с плавающей точкой из b в регистр xmm1
mulpsxmm0,xmm1;// перемножить пакеты плавающих точек: xmm0 = xmm0 * xmm1
;// xmm00 = xmm10 * xmm00
;// xmm01 = xmm11 * xmm01
;// xmm02 = xmm12 * xmm02
;// xmm03 = xmm13 * xmm03
movupsa,xmm0;// выгрузить результаты из регистра xmm0 по адресам a
};
Тот же пример, ноассемблернаявставка asm выполнена в стандарте AT&T (GNU Assembler)
floata[4]={300.0,4.0,4.0,12.0};
floatb[4]={1.5,2.5,3.5,4.5};
__asm__volatile
(
"movups %[a], %%xmm0\n\t"// поместить 4 переменные с плавающей точкой из a в регистр xmm0
"movups %[b], %%xmm1\n\t"// поместить 4 переменные с плавающей точкой из b в регистр xmm1
"mulps %%xmm1, %%xmm0\n\t"// перемножить пакеты плавающих точек: xmm0 = xmm0 * xmm1
// xmm00 = xmm00 * xmm10
// xmm01 = xmm01 * xmm11
// xmm02 = xmm02 * xmm12
// xmm03 = xmm03 * xmm13
"movups %%xmm0, %[a]\n\t"// выгрузить результаты из регистра xmm0 по адресам a
:
:[a]"m"(*a),[b]"m"(*b)
:"%xmm0","%xmm1"
);
См. также
[править|править код]Ссылки
[править|править код]- Официальное руководство по процессорам Intel, часть 2аСписок инструкций, включаяя SSE, (A-M по лат. алфавиту) приведен в п. 3.2.
- Официальное руководство по процессорам Intel, часть 2bСписок инструкций, включаяя SSE, (N-Z по лат. алфавиту) приведен в п. 4.2.
В статьене хватаетссылок на источники(см.рекомендации по поиску). |