9

我正在将一些 SSE 优化代码从 Windows 移植到 Linux。而且我发现以下在 MSVC 中运行良好的代码在 GCC 中不起作用。

代码是初始化一个数组__m128i。每个__mi28i包含 16 个int8_t。它确实使用 gcc 编译,但结果不如预期。

实际上,正如 gcc 定义__m128i的那样long long int,代码将初始化一个数组,如:

long long int coeffs_ssse3[4] = {64, 83, 64, 36}.

我用谷歌搜索并被告知“初始化向量的唯一可移植方法是使用_mm_set_XXX内在函数。” 但是,我想知道还有其他方法可以初始化__m128i数组吗?静态更好,并且不需要太多修改以下代码(因为我有大量以下格式的代码)。任何建议表示赞赏。

static const __m128i coeffs_ssse3[4] =
{
    { 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0},
    { 83, 0, 36, 0,-36,-1,-83,-1, 83, 0, 36, 0,-36,-1,-83, -1},
    { 64, 0,-64,-1,-64,-1, 64, 0, 64, 0,-64,-1,-64,-1, 64, 0},
    { 36, 0,-83,-1, 83, 0,-36,-1, 36, 0,-83,-1, 83, 0,-36,-1}
};
4

1 回答 1

9

似乎gcc没有将__m128*类型视为聚合初始化的候选者。由于它们不是标准类型,因此这种行为会因编译器而异。一种方法是将数组声明为 8 位整数的对齐数组,然后将指针转换为它:

static const int8_t coeffs[64] __attribute__((aligned(16))) =
{
     64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0,
     83, 0, 36, 0,-36,-1,-83,-1, 83, 0, 36, 0,-36,-1,-83, -1,
     64, 0,-64,-1,-64,-1, 64, 0, 64, 0,-64,-1,-64,-1, 64, 0,
     36, 0,-83,-1, 83, 0,-36,-1, 36, 0,-83,-1, 83, 0,-36,-1
};
static const __m128i *coeffs_ssse3 = (__m128i *) coeffs;

但是,我认为__attribute__((aligned(x)))Visual Studio 不支持这种语法 ( ),因此您需要#ifdef在其中使用一些技巧才能使用正确的指令在所有目标平台上实现所需的对齐。

于 2013-03-19T12:49:04.547 回答