【发布时间】: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 分量向量。仍然会生成一些条件跳转。
-
接受
constreference 的论点是明智的。您说 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的程序集吗?