2

我的问题是关于在基于内在函数的代码中定义__m128/编译时间常数的最有效位置。__m128i

考虑两种选择:

选项 A

__m128i Foo::DoMasking(const __m128i value) const
{
    //defined in method
    const __m128i mask = _mm_set1_epi32(0x00FF0000);
    return _mm_and_si128(value, mask);
}

选项 B

//Foo.h
const __m128i mask = _mm_set1_epi32(0x00FF0000);

//Foo.cpp
__m128i Foo::DoMasking(const __m128i value) const
{
    return _mm_and_si128(value, mask);
}
  • 选项 A 会导致性能损失,还是会被优化到与选项 B 相当的水平?
  • 有更好的选择 C​​吗?
  • 答案是否会根据方法是否内联而改变?
  • _mm_set1_epi32/是__mm_set_epi32加载常量的最佳方式吗?我已经看到了一些int[4]生成 an 并将其转换为__m128i.

我知道所有这些问题的正确答案是“检查拆卸!” ,但我在生成它和解释它方面都没有经验。

我正在以最大优化的方式在 MSVC 上进行编译。

4

1 回答 1

2

选项 A可能没问题 - 编译器在内联此函数时应该做正确的事情,并且应该将掩码常量从任何循环中提升出来,但根据我的经验,这是最安全的选项,特别是如果您希望它在多个平台上可靠地工作/compilers 将其重新分解为一种稍微不那么优雅但可能更有效的形式:

__m128i Foo::DoMasking(const __m128i value, const __m128i mask) const
{
    return _mm_and_si128(value, mask);
}

void Foo::DoLotsOfMasking(...)
{
    const __m128i mask = _mm_set1_epi32(0x00FF0000);

    for (int i = 0; ...; ...)
    {
        // ...
        v[i] = DoMasking(x[i], mask);
        // ...
    }
}
于 2013-10-10T08:30:31.037 回答