在Chandler Carruth的CppCon 2015演讲中,他介绍了两个神奇的函数,可以在不产生额外性能损失的情况下击败优化器。
以下是这些函数的参考代码(使用GNU风格的内联汇编):
以下是这些函数的参考代码(使用GNU风格的内联汇编):
void escape(void* p)
{
asm volatile("" : : "g"(p) : "memory");
}
void clobber()
{
asm volatile("" : : : "memory");
}
它适用于支持GNU风格内联汇编的任何编译器(GCC、Clang、英特尔编译器,可能还有其他)。然而,他提到它在MSVC中不起作用。
检查Google Benchmark的实现,似乎他们使用reinterpret cast转换为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*) {}
然而,我有两个顾虑:
- 我可能会产生一个函数调用
- 有可能“聪明”的链接时优化器会认识到UseCharPointer很小,将其内联,然后丢弃我想要保留的所有代码,或者“聪明”的优化器可能被允许执行其他我不想要的重新排序。
在MSVC中是否有任何低级等效于GNU样式汇编函数?还是这是MSVC上最好的选择?