如何将一个小常量载入一个向量?
问题描述:
请原谅我对以下问题的无知。我们支持GCC 4.8(及以上)和IBM XL C/C++ 12(及以上)。我们还在AIX和Linux上支持big和little-endian。编译器和平台使代码相当混乱。如何将一个小常量载入一个向量?
我们希望将常量1
加载到VSX寄存器中。这是我们已经能够制作的代码,但它似乎是错误的,因为它非常复杂。宏XLC_VERSION
,GCC_VERSION
和LITTLE_ENDIAN
具有它们的习惯含义,所以导致它们的附加预处理器宏已被省略。
typedef __vector unsigned char uint8x16_p8;
typedef __vector unsigned long long uint64x2_p8;
#if defined(XLC_VERSION)
typedef uint8x16_p8 VectorType;
#elif defined(GCC_VERSION)
typedef uint64x2_p8 VectorType;
#endif
#if defined(LITTLE_ENDIAN)
const VectorType one = {1};
#else
const VectorType one = (VectorType)((uint64x2_p8){0,1});
#endif
什么是不明显的是,XL C/C++支持所有的数据安排,并有一个丰富的API集。 IBM编译器很容易处理(当它不产生很难理解的警告和错误时)。
GCC回到4.8只支持64x2排列,它只有一个API子集。例如,GCC在8x16排列中缺少IBM API,而GCC没有vec_reve
(这将使endian反转变得容易)。
我真正想要做的就是这样的事情,并将它“只是工作”无处不在,但它无法编译:
VectorType one = 1;
是否有一个小常数加载到矢量不太复杂的方式寄存器?
答
你的
VectorType one = 1;
例如试图标量分配给一个载体。尝试使用矢量。对于16个字符的载体,这将是:
vector char one = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
gcc-4.8似乎编译这个好吧;我没有LE 4.8方便,但至少适用于big-endian:
0: 10 41 03 0c vspltisb v2,1
LE与gcc-5工作正常。
0: 0c 03 41 10 vspltisb v2,1
答
您可能想要检查BCD_INIT示例here。它使用宏来反转向量初始化。
关于vec_reve:这是vec_perm的语法糖。您可以将其作为头文件中的内联函数或库函数实现,并将其用于没有它的编译器。
哦,你想加载1到每个矢量插槽?或只有一个? –
@Jeremy - 只有一个;没有一个splat'd。我遇到的问题是,我们必须手动处理endian转换。例如,参见['rijndael.cpp':1152](https://github.com/weidai11/cryptopp/blob/master/rijndael-simd.cpp#L1152)。我想要一些不太复杂,更直观的东西,比如没有编译的语句。 – jww
@Jeremy - 相信与否,我花了6个小时追踪AES/CTR模式下的一次失败自测。这是因为我想'VectorType one = 1;'所以我写了'VectorType one = {1};'。它在一台小型Linux机器上运行良好,但在一台大型AIX机器上失败。现在我想添加一个避免问题的控件。这个问题试图找到我可以放置的控制,以便将来不会出现问题。 – jww