在 Chandler Carruth's CppCon 2015 talk他介绍了两个神奇的函数来击败优化器,而不会造成任何额外的性能损失。
作为引用,以下是函数(使用 GNU 风格的内联汇编):
void escape(void* p)
{
asm volatile("" : : "g"(p) : "memory");
}
void clobber()
{
asm volatile("" : : : "memory");
}
它适用于任何支持 GNU 样式内联汇编的编译器(GCC、Clang、英特尔的编译器,可能还有其他编译器)。但是,他提到它在 MSVC 中不起作用。
检查 Google Benchmark's implementation ,似乎他们使用重新解释转换为
volatile const char&
并将其传递给隐藏在非 gcc/clang 编译器上的不同翻译单元中的函数。template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
}
// some other translation unit
void UseCharPointer(char const volatile*) {}
但是,我对此有两个担忧:
MSVC 中是否有任何与 GNU 样式的汇编函数等效的较低级别的函数?还是这是 MSVC 上最好的?
最佳答案
虽然我不知道 MSVC 的等效组装技巧,但 Facebook 在他们的 Folly 基准库中使用以下内容:
/**
* Call doNotOptimizeAway(var) against variables that you use for
* benchmarking but otherwise are useless. The compiler tends to do a
* good job at eliminating unused variables, and this function fools
* it into thinking var is in fact needed.
*/
#ifdef _MSC_VER
#pragma optimize("", off)
template <class T>
void doNotOptimizeAway(T&& datum) {
datum = datum;
}
#pragma optimize("", on)
#elif defined(__clang__)
template <class T>
__attribute__((__optnone__)) void doNotOptimizeAway(T&& /* datum */) {}
#else
template <class T>
void doNotOptimizeAway(T&& datum) {
asm volatile("" : "+r" (datum));
}
#endif
Here is a link to code on GitHub.
关于visual-c++ - MSVC 中的 "Escape"和 "Clobber"等效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33975479/