Смекни!
smekni.com

Методические указания к лабораторным работам для студентов 1-го курса фпми составители (стр. 3 из 5)

обычная арифметика: x=254; x+=3; // результат x=1

арифметика с насыщением: x=254; x+=3; // результат x=255

1.2. Расширение 3DNow!

Технология 3DNow! была введена фирмой AMD в процессорах K6-2. Это была первая технология, выполняющая потоковую обработку вещественных данных. Расширение работает с регистрами 64-битными MMX, которые представляются как два 32-битных вещественных числа с одинарной точностью. Система команд расширена 21 новой инструкцией, среди которых есть команда выборки данных в кэш L1. В процессорах Athlon и Duron набор инструкций 3DNow! был несколько дополнен новыми инструкциями для работы с вещественными числами, а также инструкциями MMX и управления кэшированием.

1.3. Расширение SSE

С процессором Intel Pentium III впервые появилось расширение SSE (Streaming SIMD Extension). Это расширение работает с независимым блоком из восьми 128-битных регистров XMM0-XMM7. Каждый регистр XMM представляет собой четыре упакованных 32-битных вещественных числа с одинарной точностью. Команды блока XMM позволяют выполнять как векторные (над всеми четырьмя значениями регистра), так и скалярные операции (только над одним самым младшим значением). Кроме инструкций с блоком XMM в расширение SSE входят и дополнительные целочисленные инструкции с регистрами MMX, а также инструкции управления кэшированием.

1.4. Расширение SSE2

В процессоре Intel Pentium 4 набор инструкций получил очередное расширение – SSE2. Оно позволяет работать с 128-битными регистрами XMM как с парой упакованных 64-битных вещественных чисел двойной точности, а также с упакованными целыми числами: 16 байт, 8 слов, 4 двойных слова или 2 учетверенных (64-битных) слова. Введены новые инструкции вещественной арифметики двойной точности, инструкции целочисленной арифметики, 128-разрядные для регистров XMM и 64-разрядные для регистров MMX. Ряд старых инструкций MMX распространили и на XMM (в 128-битном варианте). Кроме того, расширена поддержка управления кэшированием и порядком исполнения операций с памятью.

1.5. Расширение SSE3

Дальнейшее расширение системы команд – SSE3 – вводится в процессоре Intel Pentium 4 с ядром Prescott. Это набор из 13 новых инструкций, работающих с блоками XMM, FPU, в том числе двух инструкций, повышающих эффективность синхронизации потоков, в частности, при использовании технологии Hyper-Threading.

1.6. Поддержка SIMD-расширений архитектурой x86-64

Процессоры AMD Athlon64 и AMD Opteron с архитектурой x86-64 поддерживают все выше перечисленные SIMD-расширения, кроме SSE3. Кроме того, число XMM регистров у этих процессоров увеличилось до 16 (XMM0-XMM15). Подробное описание типов и команд SSE приведено в приложении.

2. Встроенные функции потокового SIMD расширения

Типы данных

Для работы с векторными данными, содержащими несколько упакованных значений, используются следующие типы:

__m64 – 64-бит (регистр MMX)

1 * 64-битное целое

2 * 32-битных целых

4 * 16-битных целых

8 * 8-битных целых.

__m128 – 128-бит (регистр XMM):

4 * 32-битных вещественных (SSE),

2 * 64-битных вещественных (SSE2),

2 * 64-битное целых (SSE2),

4 * 32-битных целых (SSE2),

8 * 16-битных целых (SSE2),

16 * 8-битных целых (SSE2).

Для наибольшей эффективности элементы таких типов данных должны быть выровнены в памяти по соответствующей границе. Например, начало массива элементов типа __m64 выравнивается по 8 байтам, а массив элементов __m128 – по 16 байтам. Статические переменные и массивы компилятор выравнивает автоматически. Динамические данные компилятор обычно выравнивает по только величине 4 байта. Если данные векторных типов оказались невыровненными, то для работы с ними следует применять специальные команды невыровненного чтения и записи (они работают медленнее обычных – выровненных). Для выделения памяти с выравниванием используется функция:

void *_mm_malloc(int size, int align)

size – объем выделяемой памяти в байтах (как в malloc),

align – выравнивание в байтах.

Для освобождения памяти, выделенной таким образом, используется функция:

void _mm_free(void *p);

Например:

float *x; // массив для обработки с помощью инструкций SSE

x=(float)_mm_malloc(N*sizeof(float),16);

// … здесь обработка …

_mm_free(x);

Встроенные функции SSE для работы с вещественными числами

Заголовочный файл xmmintrin.h содержит объявления встроенных функций (intrinnsics) SSE.

Арифметические функции

Функция Инструкция Операция R0 R1 R2 R3
_mm_add_ss ADDSS сложение a0 [op] b0 a1 a2 a3
_mm_add_ps ADDPS сложение a0 [op] b0 a1 [op] b1 a2 [op] b2 a3 [op] b3
_mm_sub_ss SUBSS вычитание a0 [op] b0 a1 a2 a3
_mm_sub_ps SUBPS вычитание a0 [op] b0 a1 [op] b1 a2 [op] b2 a3 [op] b3
_mm_mul_ss MULSS умножение a0 [op] b0 a1 a2 a3
_mm_mul_ps MULPS умножение a0 [op] b0 a1 [op] b1 a2 [op] b2 a3 [op] b3
_mm_div_ss DIVSS деление a0 [op] b0 a1 a2 a3
_mm_div_ps DIVPS деление a0 [op] b0 a1 [op] b1 a2 [op] b2 a3 [op] b3
_mm_sqrt_ss SQRTSS квадратный корень [op] a0 a1 a2 a3
_mm_sqrt_ps SQRTPS квадратный корень [op] a0 [op] b1 [op] b2 [op] b3
_mm_rcp_ss RCPSS обратное значение [op] a0 a1 a2 a3
_mm_rcp_ps RCPPS обратное значение [op] a0 [op] b1 [op] b2 [op] b3
_mm_rsqrt_ss RSQRTSS обратное значение квадратного корня [op] a0 a1 a2 a3
_mm_rsqrt_ps RSQRTPS обратное значение квадратного корня [op] a0 [op] b1 [op] b2 [op] b3
_mm_min_ss MINSS минимум [op](a0,b0) a1 a2 a3
_mm_min_ps MINPS минимум [op](a0,b0) [op](a1,b1) [op](a2,b2) [op](a3,b3)
_mm_max_ss MAXSS максимум [op](a0,b0) a1 a2 a3
_mm_max_ps MAXPS максимум [op](a0,b0) [op](a1,b1) [op](a2,b2) [op](a3,b3)

Функции сравнения

Каждая встроенная функция сравнения выполняет сравнение операндов a и b. В векторной форме сравниваются четыре вещественных значения параметра a с четырьмя вещественными значениями параметра b, и возвращается 128-битная маска. В скалярной форме сравниваются младшие значения параметров, возвращается 32-битная маска, остальные три старших значения копируются из параметра a. Маска устанавливается в значение 0xffffffff для тех элементов, результат сравнения которых истина, и 0x0, где результат сравнения ложь.

Имя Сравнение Инструкция
_mm_cmpeq_ss равно CMPEQSS
_mm_cmpeq_ps равно CMPEQPS
_mm_cmplt_ss меньше CMPLTSS
_mm_cmplt_ps меньше CMPLTPS
_mm_cmple_ss меньше или равно CMPLESS
_mm_cmple_ps меньше или равно CMPLEPS
_mm_cmpgt_ss больше CMPLTSS
_mm_cmpgt_ps больше CMPLTPS
_mm_cmpge_ss больше или равно CMPLESS
_mm_cmpge_ps больше или равно CMPLEPS
_mm_cmpneq_ss не равно CMPNEQSS
_mm_cmpneq_ps не равно CMPNEQPS
_mm_cmpnlt_ss не меньше CMPNLTSS
_mm_cmpnlt_ps не меньше CMPNLTPS
_mm_cmpnle_ss не меньше или равно CMPNLESS
_mm_cmpnle_ps не меньше или равно CMPNLEPS
_mm_cmpngt_ss не больше CMPNLTSS
_mm_cmpngt_ps не больше CMPNLTPS
_mm_cmpnge_ss не больше или равно CMPNLESS
_mm_cmpnge_ps не больше или равно CMPNLEPS
_mm_cmpord_ss упорядочены CMPORDSS
_mm_cmpord_ps упорядочены CMPORDPS
_mm_cmpunord_ss неупорядочены CMPUNORDSS
_mm_cmpunord_ps неупорядочены CMPUNORDPS
_mm_comieq_ss равно COMISS
_mm_comilt_ss меньше COMISS
_mm_comile_ss меньше или равно COMISS
_mm_comigt_ss больше COMISS
_mm_comige_ss большеили равно COMISS
_mm_comineq_ss не равно COMISS
_mm_ucomieq_ss равно UCOMISS
_mm_ucomilt_ss меньше UCOMISS
_mm_ucomile_ss меньше или равно UCOMISS
_mm_ucomigt_ss больше UCOMISS
_mm_ucomige_ss больше или равно UCOMISS
_mm_ucomineq_ss не равно UCOMISS

Операции преобразования типов

Имя функции Операция Инструкция
_mm_cvtss_si32 Преобразует младший float в 32-битное целое CVTSS2SI
_mm_cvtps_pi32 Преобразует два младших float в два упакованных 32-битных целых CVTPS2PI
_mm_cvttss_si32 Преобразует младший float в 32-битное целое, отбрасывая дробную часть CVTTSS2SI
_mm_cvttps_pi32 Преобразует два младших float в два упакованных 32-битных целых, отбрасывая дробную часть CVTTPS2PI
_mm_cvtsi32_ss Преобразует 32-битное целое в float CVTSI2SS
_mm_cvtpi32_ps Преобразует два упакованных 32-битных целых в два младших float CVTTPS2PI
_mm_cvtpi16_ps Преобразует четыре упакованных 16-битных целых в упакованные float составная
_mm_cvtpu16_ps Преобразует четыре упакованных беззнаковых 16-битных целых в упакованные float составная
_mm_cvtpi8_ps Преобразует четыре младших упакованных 8-битных целых в четыре упакованных float составная
_mm_cvtpu8_ps Преобразует четыре младших упакованных беззнаковых 8-битных целых в четыре упакованных float составная
_mm_cvtpi32x2_ps Преобразует две пары упакованных 32-битных целых в четыре упакованных float составная
_mm_cvtps_pi16 Преобразует четыре упакованных float в четыре 16-битных целых составная
_mm_cvtps_pi8 Преобразует четыре упакованных float в четыре младших 8-битных целых составная