simd расширения в современных...
TRANSCRIPT
SIMD параллелизм
План
• Классификации параллелизма и параллельных ЭВМ
• ЭВМ с SIMD параллелизмом
• SIMD расширения в современных процессорах
• ведение в программирование SIMD расширений
Классификации параллелизма и
параллельных ЭВМ
Классификация Флинна
• SISD; • SIMD:
–векторные, матричные, –ассоциативные, систолические, –VLIW;
• MISD; • MIMD.
ЭВМ с SIMD параллелизмом
SIMD архитектуры
–векторные,
–матричные,
–ассоциативные,
–систолические,
–VLIW.
Векторная ЭВМ с векторным АЛУ
Векторная ЭВМ с несколькими АЛУ
Выполнение векторных операций при 2-х конвейерах
Векторные системы • Память-память:
– CDC STAR-100, Cyber-200, TI ASC,
– возможность обработки больших векторов,
– больше время запуска конвейера – не менее 100 тактов);
– Системы память-память прекратили выпускать в 1980-х г.г.
• Регистр-регистр:
– CRAY Y-MP, C-90, Fujitsu, Hitachi, NEC SX-3
– маленькая длина векторов (длинные вектора разбиваются на сегменты равного размера).
Сцепление векторов
CRAY-1 время цикла - 12.5 нс. 80 MFLOPS. При сцеплении 3-х конвейеров – 240 MFLOPS.
Earth Simulator
• 640 узлов
• 8 векторных процессоров в узле
• 16 ГБ ОЗУ в узле
• 700 ТБ внешняя память
• LINPACK 35.86 TFLOPS
• № 1 в TOP500 в 2002-2004 г.г.
Модель матричной системы
Как выполняются команды?
• Управляющие команды
• Скалярные арифметические
• Векторные арифметические
Массив ПЭ типа ПЭ-ПЭ
Массив ПЭ типа ПЭ-память
Сеть межсоединений
Возможные топологии:
• Полная связность
• Звезда
• Кольцо
• Гиперкуб
• Решетка 1-3D
• Тор 1-3D
Системная конфигурация ILLIAC IV
Разрядность: 64 бит Производительность: 1GFLOPS -> 200MFLOPS Тактовая частота: 13 МГц Внешняя память: 80МБ
Связи в матрице ПЭ ILLIAC IV
Структура ПЭ ILLIAC IV
Память: 2К слов
Connection Machine
• 1983 г.
• 65536 узлов
• 1 ИС содержит 16 процессорных элементов
• Топология соединений: – Внутри ИС – полная связность
– Гиперкуб
SIMD расширения в современных процессорах
SIMD расширения
• Цель – повышение скорости обработки потоковых данных.
• Принцип – одновременная обработка нескольких элементов данных в одной команде.
Данные для скалярной команды
Данные для векторной команды
?
Для каких задач можно применить SIMD
расширения?
Примеры задач
• локальная фильтрация сигналов;
• обработка аудиоданных;
• обработка графики;
• локальная фильтрация изображений;
• моделирование клеточного автомата;
• операции с векторами и матрицами.
Пример. Увеличение элементов массива на N
(Обычная скалярная версия)
Цикл для каждого элемента b в массиве
• b = b + N
Пример. Увеличение элементов массива на N
Обычная скалярная версия - детализация
Цикл для каждого элемента в массиве
• загрузить один элемент в регистр
• прибавить N к регистру
• сохранить результат из регистра в память
Пример. Увеличение элементов массива на N
Версия с SIMD расширениями.
Цикл для каждых 4 элементов в массиве
• загрузить 4 элемента в регистр
• прибавить N к каждому из 4-х элементов
• сохранить результат из регистра в память
SIMD расширения на x86/x86_64
• MMX
• 3DNow
• SSE
• SSE2
• SSE3
• SSE4
• AVX
Расширение MMX
8 64-битных регистров
57 инструкций
Арифметика с
Насыщением.
Регистры MMX
Регистры MMX
Регистры MMX
Регистры MMX
Арифметика с насыщением обычная арифметика
x=254; x+=3; // результат x=1
арифметика с насыщением
x=254; x+=3; // результат x=255
Предельные значения в арифметике с насыщением
Группы инструкций MMX
• Арифметические (padd[s|us][b|w|d], psub, pmul, pmad)
• Логические (pand, pandn, por, pxor) • Сравнение (pcmpeq, pcmpgt[b|w|d]) • Сдвиг (psllw, pslld, psrl, psrad) • Перемещение данных (movd, movq) • Распаковка • Преобразование формата (packsswb,
packssdw) • Прочее (emms)
Арифметическая команда
PMADDWD
Команда сравнения
PCMPEQB
Преобразование типов
Упаковка в более маленький тип Распаковка в более большой тип
Команда распаковки
PUNPCKLBW
Команда распаковки
PUNPCKHBW
Команда распаковки
PUNPCKLDQ
Ограничения MMX
• Нет чисел с плавающей запятой.
• Регистры MMX совмещены с регистрами математического сопроцессора. Нельзя одновременно использовать MMX и сопроцессор.
SIMD расширения x86
• MMX
• 3DNow
• SSE
• SSE2
• SSE3
• AVX
Расширение SSE Pentium III
8 128-битных регистров.
Операции над
4 числами float (32).
2 числами llint(64)
Векторные и скалярные
операции.
Группы FP инструкций SSE • Арифметические (ADDPS, ADDSS, SUBPS,
DIVPS, SQRTPS, RSQRTPS, MAXPS, MINPS); • Логические (ANDPS, XORPS); • Сравнение (CMPPS, CMPSS); • Сдвиг; • Перемещение данных (MOVUPS,
MOVAPS, MOVSS); • Перестановка, и распаковка элементов
(SHUFPS); • Преобразование формата.
Команда FP арифметики
ADDPS/SUBPS
Скалярная команда FP
ADDSS/SUBSS
Расширение SSE2
Pentium 4
Возможна совместная работа с сопроцессором
128-битный регистр используется как:
2 числа double 4 числа float
2, 4, 8, 16 целых чисел
Расширение SSE3
Pentium 4 с ядром Prescott
Горизонтальная обработка (сложение и вычитание значений внутри одного регистра)
Расширение AVX
Команды с двумя источниками и приемником
Введение в программирование SIMD расширений
Вопросы, возникающие при программировании с SIMD
• проверка наличия SIMD расширений;
• выбор способа, как использовать SIMD;
• выравнивание данных.
Факторы, влияющие на эффективность:
1) эффективное представление данных;
2) устранение условных операторов.
Проверка наличия SIMD
mov eax, 1 ; request version info
cpuid ; supported since Pentium
test edx, 00800000h ;bit 23
; 02000000h (bit 25) SSE
; 04000000h (bit 26) SSE2
jnz HasMMX
Как использовать SIMD из C?
• ассемблерные вставки с SIMD инструкциями процессоров;
• модули на ассемблере;
• оптимизирующие компиляторы; (gcc –O3)
• SIMD intrinsics;
• математические библиотеки.
Использование ассемблерных вставок
struct Vec4{
float x, y, z, w;
};
Vec4 A1( const Vector4 &Op_A, const Vector4 &Op_B ){
Vector4 Ret_Vector;
// ЗДЕСЬ БУДЕТ ВСТАВКА
return Ret_Vector;
}
Использование ассемблерных вставок
__asm {
MOV EAX Op_A
MOV EBX, Op_B
// Move unaligned v-s to SSE
MOVUPS XMM0, [EAX]
MOVUPS XMM1, [EBX]
ADDPS XMM0, XMM1
MOVUPS [Ret_Vector], XMM0
}
Выравнивание данных
GCC:
double a[N] __attribute__((aligned(16)));
MSVC:
__declspec(align(16)) float m_fArray[ARRAY_SIZE];
m_fArray = (float*) _aligned_malloc(ARRAY_SIZE * sizeof(float), 16);
_aligned_free(m_fArray);
Использование SIMD intrinsics
Терминология
• Intrinsic – известная компилятору функция, которая преобразуется в одну или несколько инструкций процессора.
• В intrinsic не надо работать с выделением регистров и вычислением адресов данных, как в ассемблерных вставках.
?
• Что эффективнее, обычная функция или intrinsic?
• Что эффективнее, ассемблерная вставка или intrinsic?
SIMD Intrinsics
• Встроенные функции потокового расширения.
• Цель – обеспечить работу с SIMD на языке высокого уровня
Типы данных Intrinsics _m64 - 64-бит (регистр MMX):
1 * 64-битное целое,
2 * 32-битных целых,
4 * 16-битных целых,
8 * 8-битных целых
_m128 - 128-бит (регистр XMM):
4 * 32-битных вещественных (SSE),
2 * 64-битных вещественных (SSE2)
Группы функций в Intrinsics
• Выделение памяти
• Арифметические функции
• Логические функции
• Функции сравнения
Функции выделения памяти
#include <xmmintrin.h>
float *x; // массив для обработки с помощью SSE
x=(float)_mm_malloc(N*sizeof(float),16);
// : здесь обработка :
_mm_free(x);
Арифметические функции
_mm_add_ss
_mm_add_ps
_mm_add_ss
_mm_add_ps
_mm_mul_ps
_mm_div_ps
_mm_sqrt_ps
_mm_min_ps
_mm_max_ps
__m128 _mm_add_ps
__m128 _mm_add_ps(__m128 a , __m128 b );
r0 := a0 + b0
r1 := a1 + b1
r2 := a2 + b2
r3 := a3 + b3
__m128 _mm_add_ps
__m128 _mm_sub_ps(__m128 a , __m128 b );
r0 := a0 - b0
r1 := a1 - b1
r2 := a2 - b2
r3 := a3 - b3
Логические функции
_mm_and_ps
_mm_or_ps
_mm_xor_ps
_mm_andnot_ps
Расширение SSE скалярное произведение векторов
float inner1(float *x, float* y, int n) { float s = 0; for(int i=0; i<n; ++i) s += x[i]*y[i]; return s; }
Вычисление скалярного произведения векторов x и y размера n.
Расширение SSE скалярное произведение векторов
#include <xmmintrin.h> float inner2( float* x, float* y, int n) { __m128 *xx, *yy; __m128 p,s; xx = (__m128*)x; yy = (__m128*)y; s = _mm_set_ps1(0); for(int i=0; i<n/4; ++i) { p = _mm_mul_ps(xx[i],yy[i]); s = _mm_add_ps(s,p); }
p = _mm_movehl_ps(p,s); s = _mm_add_ps(s,p); p = _mm_shuffle_ps(s,s,1); s = _mm_add_ss(s,p); float sum; _mm_store_ss(&sum,s); return sum; }
Подключение заголовочного файла xmmintrin.h, содержащего объявления
встроенных функций SSE.
x
y
n = 8
p
s
xx
yy
0 0 0 0
s
a = x[0]*y[0]+x[4]*y[4] b = x[1]*y[1]+x[5]*y[5] c = x[2]*y[2]+x[6]*y[6] d = x[3]*y[3]+x[7]*y[7]
a b c d
p c d
* * * *
=
* * * *
=
+ + + +
a+c b+d
b+d
a+c b+d
b+d
sum
_mm_set_ps1(0) устанавливает
четыре значения в одно - 0
_mm_mul_ps (_mm_add_ps) –
покомпонентное умножение (сложение)
значений типа __m128
p=_mm_movehl_ps(p,s) – перемещение
двух старших значений s в младшие p
p=_mm_shuffle_ps(s,p) – запись в
младшую позицию p второго значения s
s=_mm_add_ss(s,p) – скалярное
умножение, запись в младшую позицию
s суммы младших значений s и p
_mm_store_ss(&sum,s) – запись в
переменную sum младшего значения s
const int N = 10000000; //10M int main() { float *x, *y, s; x=(float*)_mm_malloc(N*sizeof(float),16); y=(float*)_mm_malloc(N*sizeof(float),16); for(int i=0; i<N; ++i) { x[i] = 10.0l*i/N; y[i] = 10.0l*(N-i-1)/N; } s = inner1(x,y,N); printf("Result: %f\n",s); s = inner2(x,y,N); printf("Result: %f\n",s); _mm_free(x); _mm_free(y); return 0; }
Расширение SSE скалярное произведение векторов
Выделение памяти под массивы x, y с выравниваем в 16 байт
Инициализация массивов x, y
Вычисление скалярного произведения без использования SEE-расширений
С использованием SEE-расширений
Освобождение памяти
Ссылки
1. Встроенные функции потокового SIMD расширения http://www.ccfit.nsu.ru/~kireev/lab4/lab4intr.htm
2. Streaming SIMD Extensions (SSE) http://msdn.microsoft.com/ru-ru/library/t467de55.aspx
3. Цилькер Б.Я., Орлов С.А. - Организация ЭВМ и систем. - М. - Питер. - 2006