英特尔至强融核中的排列

Posted

技术标签:

【中文标题】英特尔至强融核中的排列【英文标题】:Permutation in Intel Xeon Phi 【发布时间】:2013-03-12 07:01:58 【问题描述】:

假设我在 Xeon Phi 寄存器中有以下 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));

我怎样才能以最少的指令/周期数实现上述目标?

【问题讨论】:

【参考方案1】:

由英特尔论坛中的 Evgueni Petrov 回答:

__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”头文件中。

【讨论】:

以上是关于英特尔至强融核中的排列的主要内容,如果未能解决你的问题,请参考以下文章

我们如何知道英特尔至强融核协处理器是不是存在

英特尔至强融核上的动态内存变慢

英特尔至强融核使用的内在函数是不是比自动矢量化获得更好的性能?

英特尔至强融核协处理器是不是支持硬件级别的图形处理?

英特尔至强融核上的 MKL 3D 双精度复数 FFT

Intel Xeon Phi 上每个时钟周期的乘法次数