SSE
SSE (англ. Streaming SIMD Extensions, потоковое SIMD-расширение процессора) — это SIMD (англ. Single Instruction, Multiple Data, Одна инструкция — множество данных) набор инструкций, разработанный Intel и впервые представленный в процессорах серии Pentium III как ответ на аналогичный набор инструкций 3DNow! от AMD, который был представлен годом раньше. Первоначально названием этих инструкций было KNI — Katmai New Instructions (Katmai — название первой версии ядра процессора Pentium III).
Технология SSE позволяла преодолеть 2 основные проблемы MMX — при использовании MMX невозможно было одновременно использовать инструкции сопроцессора, так как его регистры были общими с регистрами MMX, и возможность MMX работать только с целыми числами.
SSE включает в архитектуру процессора восемь 128-битных регистров и набор инструкций, работающих со скалярными и упакованными типами данных.
Преимущество в производительности достигается в том случае, когда необходимо произвести одну и ту же последовательность действий над разными данными. В таком случае блоком SSE осуществляется распараллеливание вычислительного процесса между данными.
Содержание |
[править] Особенности
- 8 (в x86-64 - 16)128-битных регистров XMM.
- 32-битный (в x86-64 - 64) регистр флагов (MXCSR).
- 128-битный упакованный тип данных с плавающей точкой одинарной точности.
- Инструкции над вещественными числами одинарной точности.
- Инструкции явной предвыборки данных, контроля кэширования данных и контроля порядка операций сохранения.
[править] Регистры
В SSE добавлены восемь (шестнадцать) 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)
float a[4] = { 300.0, 4.0, 4.0, 12.0 };
float b[4] = { 1.5, 2.5, 3.5, 4.5 };
__asm {
movups xmm0, a ; // поместить 4 переменные с плавающей точкой из a в регистр xmm0
movups xmm1, b ; // поместить 4 переменные с плавающей точкой из b в регистр xmm1
mulps xmm1, xmm0 ; // перемножить пакеты плавающих точек: xmm1=xmm1*xmm0
; // xmm10 = xmm10*xmm00
; // xmm11 = xmm11*xmm01
; // xmm12 = xmm12*xmm02
; // xmm13 = xmm13*xmm03
movups a, xmm1 ; // выгрузить результаты из регистра xmm1 по адресам a
};
Тот же пример, но ассемблерная вставка asm выполнена в стандарте AT&T
float a[4] = { 300.0, 4.0, 4.0, 12.0 };
float b[4] = { 1.5, 2.5, 3.5, 4.5 };
asm ("movups (%[a]), %%xmm0\n" // поместить 4 переменные с плавающей точкой из a в регистр xmm0
"movups (%[b]), %%xmm1\n" // поместить 4 переменные с плавающей точкой из b в регистр xmm1
"mulps %%xmm0, %%xmm1\n" // перемножить пакеты плавающих точек: xmm1=xmm1*xmm0
// xmm10 = xmm10*xmm00
// xmm11 = xmm11*xmm01
// xmm12 = xmm12*xmm02
// xmm13 = xmm13*xmm03
"movups %%xmm1, (%[a])\n" // выгрузить результаты из регистра xmm1 по адресам a
:
:[b] "r" (b), [a] "r" (a)
:"%xmm0", "%xmm1"
);
[править] См. также
[править] Ссылки
- Корпорация Intel
- Официальное руководство по процессорам Intel, часть 2а Список инструкций, включаяя SSE, (A-M по лат. алфавиту) приведен в п. 3.2.
- Официальное руководство по процессорам Intel, часть 2b Список инструкций, включаяя SSE, (N-Z по лат. алфавиту) приведен в п. 4.2.
| Наборы расширения базовых инструкций процессоров семейства x86 |
|---|
| MMX | MMXEXT | SSE | SSE2 | SSE3 | SSSE3 | SSE4 | ATA | 3DNow! | 3DNowExt | SSE5 | AVX | AES |