c++ - 在哪里初始化 SSE 常量

标签 c++ constants sse simd

我的问题是关于在基于内在函数的代码中定义 __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] 并转换为 __m128i 的问题。

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

我正在 MSVC 上进行最大程度的优化编译。

最佳答案

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

__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);
        // ...
    }
}

关于c++ - 在哪里初始化 SSE 常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19290343/

相关文章:

尽可能快地比较缓冲区

c++ - Nextcloud 桌面客户端构建过程

php - 在 php 中定义你自己的魔法常量?

c++ - C++ 中的 MD5 实现返回错误的摘要

c++ - 在单独的函数中修改指向字符串文字的指针

c++ - 为什么不将模板类型参数推断为 'const' ?

c - 根据比较将浮点变量设置为 0.0f 或 1.0f 的 SSE 代码

assembly - 对于memcmp,SSE4.2字符串指令比SSE2快多少?

c++ - 如何使用内联汇编模拟以下 C++ 代码?

c++ - mem_func 和虚函数