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*) {}

但是,我有两个担忧:

  • 我可能会招致一个函数调用
  • 有一种可能性:“巧妙的”链接时间优化器可能会识别UseCharPointer很小,将它内联,然后放弃我想要保留的所有代码,或者可以允许“聪明”优化器执行其他重新排序。想要它。
  • 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

    上一篇: "Escape" and "Clobber" equivalent in MSVC

    下一篇: MSVC /FA GCC equivalent