2013-03-12 75 views
1

假設我在至強融核雙打的以下4個向量寄存器:排列在英特爾至強融核

A-> |a8|a7|a6|a5|a4|a3|a2|a1| 
B-> |b8|b7|b6|b5|b4|b3|b2|b1| 
C-> |c8|c7|c6|c5|c4|c3|c2|c1| 
D-> |d8|d7|d6|d5|d4|d3|d2|d1| 

我想將它們置換成如下:

A_new ->|d2|d1|c2|c1|b2|b1|a2|a1| 
B_new ->|d4|d3|c4|c3|b4|b3|a4|a3| 
C_new ->|d6|d5|c6|c5|b6|b5|a6|a5| 
D_new ->|d8|d7|c8|c7|b8|b7|a8|a7| 

的目標是讓:

O = _mm512_add_pd(_mm512_add_pd(A_new,B_new),_mm512_add_pd(C_new,D_new)); 

如何以最少數量的指令/週期完成上述操作?

回答

0

由葉夫根尼·彼得羅夫在英特爾論壇上回答:

__m512i a1 = (__m512i)_mm512_mask_blend_pd(0x33, B, _mm512_swizzle_pd(A, _MM_SWIZ_REG_BADC)); 
__m512i a0 = (__m512i)_mm512_mask_blend_pd(0xcc, A, _mm512_swizzle_pd(B, _MM_SWIZ_REG_BADC)); 
__m512i a3 = (__m512i)_mm512_mask_blend_pd(0x33, D, _mm512_swizzle_pd(C, _MM_SWIZ_REG_BADC)); 
__m512i a2 = (__m512i)_mm512_mask_blend_pd(0xcc, C, _mm512_swizzle_pd(D, _MM_SWIZ_REG_BADC)); 

__m512d C_new = (__m512d)_mm512_mask_alignr_epi32(a2, 0x00ff, a0, a0, 8); 
__m512d A_new = (__m512d)_mm512_mask_alignr_epi32(a0, 0xff00, a2, a2, 8); 
__m512d D_new = (__m512d)_mm512_mask_alignr_epi32(a3, 0x00ff, a1, a1, 8); 
__m512d B_new = (__m512d)_mm512_mask_alignr_epi32(a1, 0xff00, a3, a3, 8); 

截至發稿時,_mm512_mask_blend_pd()內部是不是英特爾C++用戶指南中提到的,但應該很快就會得到糾正。它存在於「zmmintrin.h」頭文件中。