我尝试过使用clang extended vectors。三元运算符应该可以工作,但它对我不起作用。例如:
int main()
{
using int4 = int __attribute__((ext_vector_type(4)));
int4 a{0, 1, 3, 4};
int4 b{2, 1, 4, 5};
auto const r(a - b ? a : b);
return 0;
}
请提供一些示例,告诉我如何使其工作,就像它在OpenCL下工作一样。我正在使用clang-3.4.2
。
错误:
t.cpp:8:16: error: value of type 'int __attribute__((ext_vector_type(4)))' is not contextually convertible to 'bool'
auto const r(a - b ? a : b);
^~~~~
1 error generated.
答案 0 :(得分:2)
您可以直接在Clang中循环遍历元素。这是GCC和Clang的解决方案。
#include <inttypes.h>
#include <x86intrin.h>
#if defined(__clang__)
typedef float float4 __attribute__ ((ext_vector_type(4)));
typedef int int4 __attribute__ ((ext_vector_type(4)));
#else
typedef float float4 __attribute__ ((vector_size (sizeof(float)*4)));
typedef int int4 __attribute__ ((vector_size (sizeof(int)*4)));
#endif
float4 select(int4 s, float4 a, float4 b) {
float4 c;
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
c = s ? a : b;
#else
for(int i=0; i<4; i++) c[i] = s[i] ? a[i] : b[i];
#endif
return c;
}
两者都生成
select(int __vector(4), float __vector(4), float __vector(4)):
pxor xmm3, xmm3
pcmpeqd xmm0, xmm3
blendvps xmm1, xmm2, xmm0
movaps xmm0, xmm1
ret
但使用AVX512最好使用遮罩(例如__mmask16
)。
答案 1 :(得分:1)
这有点紧迫:
auto const diff = a-b;
auto const ra( - (diff!=zero) * a - (diff==zero) *b);
我想这是编译器或您链接的文档中的错误。
答案 2 :(得分:0)
最后我接受了这个:
#if defined(__clang__)
template <typename U, typename V>
constexpr inline std::enable_if_t<
!std::is_arithmetic<V>{},
V
>
select(V const a, V const b, U const c) noexcept
{
return V((c & U(a)) | (~c & U(b)));
}
#else
template <typename U, typename V>
constexpr inline std::enable_if_t<
!std::is_arithmetic<V>{},
V
>
select(V const a, V const b, U const c) noexcept
{
return c ? a : b;
}
#endif
同样可以通过其他方式完成,例如,使用索引技巧,但它可能不会很好地优化(我不想在那里有任何条件)。