2015-02-22 2 views
1

Существуют ли встроенные инструкции для выполнения операции правого и левого сдвига для (16-разрядных) целых элементов в AVX2?Целые числа сдвига AVX2 (16-разрядные)

Как следующими примерами:

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] --> [16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 

и

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] --> [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] 

, где _mm_srli_si128(H,14) и _mm_slli_si128(H,2) хорошо работают на SSE3 16-битовых элементов. Я спрашиваю, потому что производительность (время работы) имеет решающее значение для меня.

+1

Дубликаты: [8 бит сдвиг в AVX2 со сдвигом в нулях] (http://stackoverflow.com/questions/20775005/8-bit-shift-operation-in-avx2-with-shifting-in-zeros) и [Эмуляция сдвигов по 32 байтам с AVX] (http://stackoverflow.com/questions/25248766/emulating-shifts-on-32-bytes-with-avx) и –

+1

Большое спасибо Mr. @PaulR – MROF

ответ

1

К сожалению, таких инструкций в AVX2 нет. Все инструкции AVX2 SSE2 расширены до 256 бит, имея в виду совместимость при использовании в 128-разрядном SSE2.

Если вам известно, что число 16-разрядных целых чисел сдвигается во время компиляции, вы можете использовать комбинацию перестановок и сдвигов. Например. вы можете логически разбить это значение на 64-битные куски, переставить сдвиги этих блоков и объединить их.

Вот как я делаю это в моем коде

static __m256i m256_srl16_1(__m256i i) { 
    // suppose i is [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1] 

    //[4, 3, 2, 1,  16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5] 
    __m256i srl64_q = _mm256_permute4x64_epi64(i, _MM_SHUFFLE(0,3,2,1)); 

    //[ 1, 0, 0, 0  13, 0, 0, 0  9, 0, 0, 0  5, 0, 0, 0] 
    __m256i srl64_m = _mm256_slli_epi64(srl64_q, 3*16); 
    //[ 0, 16, 15, 14, 0, 12, 11, 10, 0, 8, 7, 6,  0, 4, 3, 2] 
    __m256i srl16_z = _mm256_srli_epi64(i, 1*16); 

    __m256i srl64 = _mm256_and_si256(srl64_m, _mm256_set_epi64x(0, ~0, ~0, ~0)); 
    __m256i r = _mm256_or_si256(srl64, srl16_z); 

    return r; 
} 

Если вам нужно перейти на более чем 64 бит, вам требуется дополнительная перестановку исходного значения и маскировки ненужные биты

+0

Вы можете использовать ['_mm256_blend_epi32' ] (http://felixcloutier.com/x86/VPBLENDD.html) для более эффективной комбинации в конце, если сдвиг кратен 4 байтам. В противном случае может быть комбинация этого и '_mm256_blend_epi16' (где тот же самый непосредственный контроль используется для обеих полос 128b). –

+0

Также полезно: '_mm256_shuffle_epi8' помещать каждый байт на свою полосу или обнулять его. –

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