【问题标题】:an optimal select function for vector extensions?矢量扩展的最佳选择功能?
【发布时间】:2014-08-18 07:39:08
【问题描述】:

OpenCL 有一个 select function,可用于全向量参数。 clang 和 gcc 都支持向量类型,但目前只有 gcc 支持支持向量的三元运算符,并且它们都没有类似 OpenCL 的 select 函数。我试图实现一个替换,但结果不是最优的,gcc 和 clang 都会产生条件跳转。但是,gcc 的三元运算符做得很好,因此它非常适合作为替代品。是否存在类似select 的函数的最佳解决方案(尤其是在 clang 下),它是什么?以下是一些非最佳的想法:

template <typename U, typename V>
inline V select(U const s, V const a, V const b) noexcept
{
// a for loop gives horrible results
/*
  constexpr U zero{}; // for clang only

  return (-(s != zero) * a) - ((s == zero) * b);
*/
  return V{
    s[0] ? a[0] : b[0],
    s[1] ? a[1] : b[1],
    s[2] ? a[2] : b[2],
    s[3] ? a[3] : b[3]
  }; // for 4-component vectors only, one could generalize with the indices trick
/*
  return s ? a : b; // for gcc
*/
}

【问题讨论】:

  • 您可以编写一个模板来为 n 元向量生成展开循环
  • @Manu343726 是的,我知道,但我不想让我的问题复杂化,所以我手动展开了一个 4 分量向量。仍然会生成一些条件跳转。
  • 接受const reference 的论点是明智的。您说 clang 的三元运算符产生了错误的代码,但是 1)没有说明您认为它是如何低效或更好的(作为 asm 级别),以及 2)没有列出 clang 版本/命令行标志......?你有什么for 循环代码产生了错误的输出?
  • @TonyD 1) clang 根本不提供向量类型的三元运算符,但 gcc 提供了,我按值接受以鼓励传入寄存器。 2) -O3 clang-3.4.2 3) V result; for(unsigned i{}; i != 4; ++i) result[i] = s[i] ? a[i] : b[i]; return result; 根本没有展开。坏代码基本上是条件分支。使用 gcc 的三元运算符时,这些情况很少发生(从未见过)。
  • 1) 它与支持vectors 的三元运算符无关...您的代码在三元运算符启动之前提取对向量元素的引用,3) 具有未定义的行为 - 索引最后 - 您可以尝试 V result(4); 立即分配必要的大小。 GCC 的 ? 经常生成条件分支(实际上并没有很多选项 - 你希望它做什么?)...你可以发布你说不是条件分支的 GCC -S 的程序集吗?

标签: c++ gcc c++11 clang simd


【解决方案1】:

这在 gcc 和 clang 下都编译成半好代码:

template <typename U, typename V>
constexpr inline V select(U const s, V const a, V const b) noexcept
{      
  return V((s & U(a)) | (~s & U(b)));
}

asm 清单:

Dump of assembler code for function select<int __vector(4), float __vector(4)>(int __vector(4), float __vector(4), float __vector(4)):
   0x00000000004009c0 <+0>:     andps  %xmm0,%xmm1
   0x00000000004009c3 <+3>:     andnps %xmm2,%xmm0
   0x00000000004009c6 <+6>:     orps   %xmm1,%xmm0
   0x00000000004009c9 <+9>:     retq   
End of assembler dump.

这仍然不如优化器产生的那么好。它的工作方式是滥用向量转换和事实,即比较操作在比较匹配的地方产生-1(全1)整数。至少不需要算术运算。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 2015-05-20
    • 1970-01-01
    相关资源
    最近更新 更多