MSVC中的“Escape”和“Clobber”等效
在Chandler Carruth的CppCon 2015演讲中,他介绍了击败优化器的两个神奇功能,没有任何额外的性能损失。
作为参考,这里是功能(使用GNU风格的内联汇编):
void escape(void* p)
{
asm volatile("" : : "g"(p) : "memory");
}
void clobber()
{
asm volatile("" : : : "memory");
}
它适用于任何支持GNU风格内联汇编(GCC,Clang,Intel编译器,可能还有其他)的编译器。 但是,他提到它在MSVC中不起作用。
检查Google Benchmark的实现,似乎他们使用重新解释转换为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
这里是GitHub上的代码链接。
链接地址: http://www.djcxy.com/p/72527.html