intel - 了解 Intel Intrinsics Guide 中的代码示例

标签 intel sse simd intrinsics avx

我正在尝试了解 _mm256_permute2f128_ps() 的作用,但无法完全理解 intel's code-example .

DEFINE SELECT4(src1, src2, control) {
    CASE(control[1:0]) OF
    0:  tmp[127:0] := src1[127:0]
    1:  tmp[127:0] := src1[255:128]
    2:  tmp[127:0] := src2[127:0]
    3:  tmp[127:0] := src2[255:128]
    ESAC
    IF control[3]
        tmp[127:0] := 0
    FI
    RETURN tmp[127:0]
}
dst[127:0] := SELECT4(a[255:0], b[255:0], imm8[3:0])
dst[255:128] := SELECT4(a[255:0], b[255:0], imm8[7:4])
dst[MAX:256] := 0

具体的我不懂:

  • imm8[3:0] 符号。他们将其用作 4 字节掩码吗? But I've seen people invoke _mm256_permute2f128_pd(myVec, myVec, 5),其中 imm8 用作数字(数字 5)。

  • SELECT4 函数中,control[1:0] 是什么意思?控件是字节掩码还是用作数字?它由多少字节组成?

  • 为什么 IF control[3] 在 intel 的例子中使用。它不会撤消 CASE 中的选择 3: 吗?为什么我们要将 tmp[127 to 0] 设置为零,如果我们一直在输出它?

最佳答案

在这种情况下,[x:y] 符号始终指代位号。例如,如果您将 5 作为 imm8 参数传递,则(因为 5==0b00000101)imm8[3:0]==0b0101==5,如果它作为 control 传递给 SELECT4 宏,您将得到 control[3]==0==false控制[1:0]==0b01==1control[2] 位将被忽略。

全面评估这个,你得到

dst[127:0]   := SELECT4(a[255:0], b[255:0], 5) == a[255:128]
dst[255:128] := SELECT4(a[255:0], b[255:0], 0) == a[127:0]

这意味着这将切换 a 寄存器的上半部分和下半部分并将其存储到 dst 寄存器中。

dst[MAX:256] := 0 仅与具有较大寄存器的架构相关(如果您有 AVX-512),即,它将位 255 以上的所有内容设置为零。这与传统的 SSE 指令形成对比,后者(如果在支持 AVX 的 CPU 上执行)会使上半部分保持不变(并产生错误的依赖关系——参见 this related question)。

关于intel - 了解 Intel Intrinsics Guide 中的代码示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57727659/

相关文章:

c++ - 使用正确数量的逻辑处理器

c - 为什么同一程序中同一 C 循环的相同副本会花费明显但始终不同的时间来执行?

clang - Clang 的 '_mm256_pow_ps' 内在函数在哪里?

c - AVX2 中的 8 位移位操作,移入零

c++ - SIMD 内部函数 : aligned operation different than unaligned?

c++ - 使用 SIMD 将 10 位值打包成字节流

intel - 英特尔为什么不以更加兼容或通用的方式设计其SIMD ISA?

linux - 我如何处理 Assembly(IA32) 中的幂函数和平方根函数?

c++ - CPU 架构的 8 位 FFT?