SSE:我应该将洗牌掩码设置为静态变量吗?

Posted

技术标签:

【中文标题】SSE:我应该将洗牌掩码设置为静态变量吗?【英文标题】:SSE: Should I set a shuffle mask as static variable or not? 【发布时间】:2014-01-17 10:57:05 【问题描述】:

如果在函数中我需要一个固定的随机播放掩码,我应该将其设置为const 还是static const

const __m128i SHUFFLE_MASK = _mm_setr_epi8(0,  4,  8, 12, -1, -1, -1, -1,
                                           -1, -1, -1, -1, -1, -1, -1, -1);

static const __m128i SHUFFLE_MASK = _mm_setr_epi8(0,  4,  8, 12, -1, -1, -1, -1,
                                                  -1, -1, -1, -1, -1, -1, -1, -1);

【问题讨论】:

C++ semantics of `static const` vs `const`的可能重复 @Adriano 我不知道这是否真的有区别,但我正在使用一个函数来初始化变量,而不是常量。附带说明一下,该函数不是静态函数。 函数是否为静态 IMO 无关紧要(因为无论您使用的是函数还是文字值,它都不是 constexpr)。无论如何,我会使用 static const ,因为乍一看你只做一次计算(但这里的编译器可能比我们预期的要聪明得多,所以检查生成的代码可能比我的猜测更有用)。 我同意 Adriano - 检查生成的代码。就我而言,静态 const 变量要糟糕得多,因为 g++ 生成代码来检查是否每次都设置了变量。 YMMV。 【参考方案1】:

通常_mm_setr_epi8 的编译时间常数数据最终会编译成一个 16B 的只读数据块,该数据块会被加载(或用作内存操作数)。 (在gcc -S asm 输出中查找.LC0 之类的标签)。这已经是最优的了。

Emil Styrke 评论说,static const 最终可以包含检查静态位置是否已初始化的代码。由于没有任何好处,而且可能会产生成本(至少在较旧的 gcc 上,我自己还没有检查过),因此请避免将 static const 用于向量(尤其是当声明和初始化程序位于函数内部时)。

IDK 如果 gcc 曾经将数据中具有模式的 setr 优化为 movd 并随机播放,或类似的东西。如果是这样,那么您可能希望避免使用指令生成常量,而不是将其作为内存操作数。

不过,这似乎不太可能发生。但是,如果您需要破坏这种优化,您可以使用静态(文件范围)char 数组来保存常量,并将指针转换为向量类型。

【讨论】:

以上是关于SSE:我应该将洗牌掩码设置为静态变量吗?的主要内容,如果未能解决你的问题,请参考以下文章

将变量放在 AppDelegate 中是 Swift 中静态变量的解决方法吗?

C ++为将(静态)const全局变量设置为另一个静态const变量而给出编译器错误

静态成员变量初始化 C++

lua脚本有静态局部变量吗

请教大家关于JAVA中的静态变量和静态方法

何时选择变量来声明为最终静态