GCC C向量扩展:如何将向量的内容向左移动一个元素



我是GCC C向量扩展的新手。我正在考虑在我的项目中使用它们,但它们的效用(在某种程度上)取决于有效地将向量中的所有元素向左移动一个位置并将结果存储在新向量中的能力。我如何才能有效地做到这一点(比如以simd加速的方式)?

所以,基本上:

    OriginalVector = {1,2,3,4,5,6,7,8}
  • shiftevector = {2,3,4,5,6,7,8, X}(X可以是任意值)

背景信息(您可以跳过这个):这种转换的目的是处理矩阵,其中每一行都用向量表示。具体来说,它允许将shiftevector作为下一行的左上角对角线,并在一个SIMD操作中比较所有值。如果有另一种方法将一个向量与另一个偏移了一个元素的向量进行比较,那也可以解决这个问题。但我不这么认为,执行这种比较的最有效方法是将所有元素向左移动,并以1:1的比例进行比较。

一般规定:

  • 在此过程中不能损坏原载体
  • 如果我必须使用某种x86固有功能,但我不知道是哪一种或如何使用
  • 如果我在矢量中丢失最左边的元素并在最右边引入乱码,这是可以的
  • 如果最有效的方法是原始矢量从第二个位置到结束+1的未对齐加载,这是很好的,但我仍然想知道如何最好地编写此

这里的瓶颈似乎是缺乏关于使用intrinsic过程的一般信息。似乎人们要么使用汇编(我不是专家),要么使用自动向量化(在这里不太好用),所以向量类型是最合乎逻辑的选择。

谢谢!

在手册的深处,我发现了这一点愚蠢:

typedef int v8si __attribute__ ((vector_size (32)));
v8si OriginalVector, masker, ShiftedVector;
OriginalVector = {1, 2, 3, 4, 5, 6, 7, 8};
masker = {1,2,3,4,5,6,7,0};
ShiftedVector = __builtin_shuffle(OriginalVector, masker);

我在"masker"后面无缘无故地放了一个0(任何0-7的元素都可以)。它所做的只是将原始元素映射到掩码中定义的位置,并将它们保存到结果中。

但是,虽然这是一个答案,它可能不是"最好"的答案,因为我想象有一个更好的方法比创建一个新的向量,占用一个寄存器的新向量,分配位置,把每个元素的位置,并把它放在另一个任意的地方,并保存结果。

是的,我们可以在循环之外缓存掩码器,而不是每次都创建它,但我想在某个地方有一些简单的"向左排列"指令,可以滑动它…

最快的移动是不移动(即不移动,不复制):

int Data[16] = {
    1, 2, 3, 4, 5, 6, 7, 8,
    0, 0, 0, 0, 0, 0, 0, 0,
};
int* Ptr = Data;
// first shift
Ptr++;
// second shift
Ptr++;
// and so on.

如果算法允许(即移位的数量是有限的,并且事先知道),则可以保留足够的空间,并通过增加指针来进行"移位"。

最新更新