问题描述
在钱德勒·卡鲁斯(Chandler Carruth)的CppCon 2015演讲中,他介绍了两个神奇的功能,它们可以击败优化器而不会造成任何额外的性能损失.
In Chandler Carruth's CppCon 2015 talk he introduces two magical functions for defeating the optimizer without any extra performance penalties.
作为参考,以下是函数(使用GNU风格的内联汇编):
For reference, here are the functions (using GNU-style inline assembly):
void escape(void* p)
{
asm volatile("" : : "g"(p) : "memory");
}
void clobber()
{
asm volatile("" : : : "memory");
}
它可在任何支持GNU风格内联汇编的编译器(GCC,Clang,Intel的编译器,可能还有其他编译器)上使用.但是,他提到它在MSVC中不起作用.
It works on any compiler which supports GNU-style inline assembly (GCC, Clang, Intel's compiler, possibly others). However, he mentions it doesn't work in MSVC.
检查 Google Benchmark的实现,似乎他们使用了重新解释的强制转换volatile const char&
并将其传递给非gcc/clang编译器上其他翻译单元中隐藏的函数.
Examining Google Benchmark's implementation, it seems they use a reinterpret cast to a volatile const char&
and passes it to a function hidden in a different translation unit on non-gcc/clang compilers.
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*) {}
但是,我对此有两个担忧:
However, there are two concerns I have with this:
- 我可能会发生函数调用
- 智能"链接时优化器可能会发现UseCharPointer很小,将其内联,然后丢弃我想要保留的所有代码,或者可能允许智能"优化器执行其他重新排序不想.
MSVC中是否有与GNU样式的汇编函数相当的低级等效项?还是这是MSVC上最好的?
Is there any lower-level equivalent in MSVC to the GNU-style assembly functions? Or is this the best it gets on MSVC?
推荐答案
虽然我不知道MSVC的等效汇编技巧,但Facebook在其Folly基准测试库中使用了以下内容:
While I don't know of an equivalent assembly trick for MSVC, Facebook uses the following in their Folly benchmark library:
/**
* 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
这篇关于“逃脱"和“口语"在MSVC中等效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!