我是GCC的C矢量扩展的新手.根据手册,将一个向量与另一个向量进行比较的结果(test = vec1> vec2;)是"test"在每个元素中包含0,为false,每个元素中为-1为真.
但是如何快速检查是否有任何元素比较是真的?而且,进一步说,如何判断哪个是比较真实的第一个元素?
例如,用:
vec1 = {1,1,3,1};
vec2 = {1,2,2,2};
test = vec1 > vec2;
Run Code Online (Sandbox Code Playgroud)
我想确定"test"是否包含任何真值(非零元素).在这种情况下,我希望"test"减少为true,因为存在一个vec1大于vec2的元素,因此test中的元素包含-1.
另外,或者,我想快速发现WHICH元素未通过测试.在这种情况下,这只是数字2.换句话说,我想测试哪个是第一个非零元素.
int hasAnyTruth = ...; // should be non-zero. "bool" works too since C99
int whichTrue = ...; // should contain 2, because test[2] == -1
Run Code Online (Sandbox Code Playgroud)
我想我们可以使用simd reduction-addition命令(?)将向量中的所有内容加到一个数字中并将该总和与0进行比较,但我不知道如何(或者是否有更快的方法).我猜第二个问题需要某种形式的argmax,但同样,我不知道如何指示GCC在矢量上使用它.
英特尔至强披"骑士降落"处理器将是第一个支持AVX-512,但它只能支持"F"(如无SSE SSE2,或不AVX AVX2),所以浮点东西为主.
我正在编写使用内部函数通过SSE4.1指令操作字节和字(8位和16位)的软件.
我很困惑,是否会出现在AVX-512F全部/大部分SSE4.1指令EVEX编码的版本,以及这是否意味着我可以期待我的SSE代码来自动获取EVEX扩展指令和映射到所有新的寄存器.
维基百科说:
SIMD寄存器文件的宽度从256位增加到512位,共有32个寄存器ZMM0-ZMM31.如256位的YMM从AVX扩展和从流SIMD扩展128位XMM寄存器寄存器,这些寄存器可被寻址,和遗留AVX和SSE指令可以扩展到在16个附加寄存器XMM16-XMM31和YMM16-YMM31使用EVEX当操作编码形式.
这不幸的是没有澄清是否编译SSE4代码启用AVX512,会导致相同的(真棒)加速比它编译成AVX2提供(的传统指令VEX编码).
有人知道为AVX-512F编译SSE2/4代码(C内在函数)会发生什么?人们可以期待像AVX1的字节和字指令的VEX编码那样的速度颠簸吗?
背景:GCC C 的内置向量扩展允许将 SIMD 向量相当自然地表示为 C“类型”。根据文档,支持许多内置操作(+、- 等)。但是,由于某种原因,三元运算符以及逻辑运算符(&&、||)只能在 C++ 中使用。这是 all=C 代码库的问题。
问题:在 GCC C 中,如何实现与 SIMD 兼容的 [branchless] 形式的条件:
v4si a = {2,-1,3,4}, b, indicesLessThan0;
indicesLessThan0 = a < 0;
b = indicesLessThan0 ? a : 0;
Run Code Online (Sandbox Code Playgroud)
而且,更一般地说,如何根据相同的结果执行任意独立的语句块:
v4si c = {9,8,7,6}, d;
for (int i = 0; i < 4; i++) {
if (indicesLessThan0[i]) { // consider tests one by one
b[i] = a[i] // as the ternary operator does above
d[i] = c[i] + 1; // some other …
Run Code Online (Sandbox Code Playgroud)