【问题标题】:Why is the last argument of _mm_permute_ps an int?为什么 _mm_permute_ps 的最后一个参数是 int?
【发布时间】:2019-08-23 01:20:19
【问题描述】:

GCC 好心地告诉我 SIMD 内在 _mm_permute_ps 的最后一个参数必须是 8 位立即数。那么为什么它的最后一个参数声明为期待int

__m128     _mm_permute_ps(__m128  a, int imm8);
__m256d _mm256_permute_pd(__m256d a, int imm8);

8 位类型参数不会为最终用户提供更有用的界面吗?

【问题讨论】:

  • 责备英特尔。他们提出了内在函数。
  • 如果它必须是一个立即值,它真的有什么不同吗?
  • 有一种观点认为“每个整数都应该是int 类型,除非有充分的理由让它成为其他类型”。根据我跨越三个十年的经验,我倾向于同意这种设计理念。正如@immibis 指出的那样,这里似乎没有“该死的好理由”。
  • 而且,根据文档,它实际上只有 4 位(对于两个功能)。
  • @immibis:硬件会忽略[7:4] 位,但机器编码使用imm8 的整个字节。你当然可以放任何你想要的东西。 (没关系;你不是用 asm 写的,所以不能保证编译器生成的 asm 甚至会包含一个 vpermilps,更不用说使用你的直接不变了。例如,clang 的 shuffle 优化器可能会忘记被忽略的位。)

标签: c intel api-design intrinsics avx


【解决方案1】:

它与所有其他采用 shuffle 向量或立即参数的内在函数一致。可能是为了表明它是一个整数而不是一个字符,同时避免依赖 stdint.h 的 int8_t。

从 C++ 的角度来看,更有趣的部分是它不是 constexpr,因此您可以给它非编译时参数,这会为编译器带来有趣的东西。我曾经尝试以一种假设直接参数是编译时的方式改进 gcc 的内在函数,但它破坏了数量惊人的代码。

【讨论】:

  • 如果它不是编译时常量,一些编译器会拒绝它。 IMO,这是正确的行为,因为这些内在函数应该紧密映射到它所代表的指令,而不是需要通过任何必要手段实现的抽象接口。
  • GCC 仍然需要与立即数相对应的内在参数作为编译时常量内联后。所以对于非优化代码,_mm_shuffle_epi32 的定义在__builtin_ia32_pshufd 方面是一个宏,而#ifdef __OPTIMIZE__ 版本是一个用__attribute__((__gnu_inline__, __always_inline__, __artificial__)) 声明的内联函数。但即使这样也不足以让它在-O0 上工作,因为这种非优化级别意味着即使在强制内联之后,常量传播也不起作用。
猜你喜欢
  • 1970-01-01
  • 2023-03-11
  • 2021-02-26
  • 2012-03-11
  • 2017-05-14
  • 2015-06-19
  • 2019-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多