"Escape" and "Clobber" equivalent in MSVC
In Chandler Carruth's CppCon 2015 talk he introduces two magical functions for defeating the optimizer without any extra performance penalties.
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");
}
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.
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:
Is there any lower-level equivalent in MSVC to the GNU-style assembly functions? Or is this the best it gets on MSVC?
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
Here is a link to code on GitHub.
链接地址: http://www.djcxy.com/p/72528.html