请原谅我对以下问题的无知。我们支持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;
是否有一个小常数加载到矢量不太复杂的方式寄存器?
哦,你想加载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