2012-06-03 2 views
5

Я работаю с набором инструкций SSE2 в MS Visual Studio. Я использую его для выполнения некоторых расчетов с 16-разрядными данными.Как эффективно определить 128-битную константу?

Предположим, что у меня есть 8 значений, загруженных в регистр SSE. Я хочу добавить константу (например, 42) ко всем из них. Вот как я хотел бы, чтобы мой код выглядел.

__m128i values; // 8 values, 16 bits each 
const __m128i my_const_42 = ???; // What should i write here? 
values = _mm_add_epi16(values, my_const_2); // Add 42 to the 8 values 

Теперь, как я могу определить константу? Следующие два способа работают, но один неэффективен, а другой уродлив.

  1. my_const_42 = _mm_set_epi16(42, 42, 42, 42, 42, 42, 42, 42) - компилятор генерирует 8 команд "построить" константа
  2. my_const_42 = {42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0} - трудно понять, что происходит; изменение 42, например. -42 не является тривиальным

Есть ли способ выразить 128-битную константу удобнее?

+1

Возможно, использование макроса для второго метода в порядке – valdo

ответ

8

Девяносто процентов битвы находят правильное внутреннее. Библиотека MSDN довольно хорошо организована, начиная с this page. Оттуда, просверлить вниз, как это:

  • Вы знаете, что вы хотите использовать «MMX, SSE и SSE2 Intrinsics», нажмите на эту ссылку
  • Вы знаете, что вы хотите использовать «Streaming SIMD Extensions 2», нажмите что ссылка
  • Следующая привлекательная ссылка «Integer памяти и инициализация», так как вы не хотите с плавающей точкой
  • вы получите две соответствующие ссылки, загрузка и установка операций
  • нагрузки просто получает вас те, что вы уже нашли

Комплект золотой, из попса _mm_set1_epi16 (short w)

2

Что-то примечание о создании констант в SSE (или NEON). Загрузка данных из памяти происходит крайне медленно по сравнению с выполнением команд. Если вам нужна константа, которую можно создать с помощью кода, то это более быстрый выбор. Вот несколько примеров констант, созданных с помощью кода:

xmmTemp = _mm_cmpeq_epi16(xmmA, xmmA); // FFFF 
xmmTemp = _mm_slli_epi16 (mmxTemp, 7); // now it has 0xFF80 (-128) 

xmmTemp = _mm_cmpeq_epi16(xmmA, xmmA); // FFFF 
xmmTemp = _mm_slli_epi16 (mmxTemp, 15); // 0x8000 
xmmTemp = _mm_srli_epi16 (mmxTemp, 11); // 0x10 (positive 16) 

 Смежные вопросы

  • Нет связанных вопросов^_^