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

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

 

Встроенные функции потокового 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-битных целых составная

Другие функции

Имя функции Операция Инструкция
_mm_shuffle_ps перестановка упакованных значений SHUFPS
_mm_shuffle_pi16 перестановка упакованных значений PSHUFW
_mm_unpackhi_ps выборка старших значений UNPCKHPS
_mm_unpacklo_ps выборка младших значений UNPCKLPS
_mm_loadh_pi загрузка старших значений MOVHPS reg, mem
_mm_storeh_pi сохранение старших значений MOVHPS mem, reg
_mm_movehl_ps копирование старшей половины в младшую MOVHLPS
_mm_movelh_ps копирование младшей половины в старшую MOVLHPS
_mm_loadl_pi загрузка младших значений MOVLPS reg, mem
_mm_storel_pi сохранение младших значений MOVLPS mem, reg
_mm_movemask_ps создание знаковой маски MOVMSKPS
_mm_getcsr сохранить регистр состояния STMXCSR
_mm_setcsr установить регистр состояния LDMXCSR

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: