"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:

  • I'm potentially incurring a function call
  • There is the possibility a "clever" link-time optimizer might recognize UseCharPointer is small, inline it, then discard all the code I wanted kept around, or a "clever" optimizer might be allowed to perform other re-orderings I don't want it to.
  • 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

    上一篇: msvc std :: function不接受带有嵌套lambda的通用lambda

    下一篇: MSVC中的“Escape”和“Clobber”等效