visual-c++ - MSVC 中的 "Escape"和 "Clobber"等效

标签 visual-c++ benchmarking microbenchmark

Chandler Carruth's CppCon 2015 talk他介绍了两个神奇的函数来击败优化器,而不会造成任何额外的性能损失。

作为引用,以下是函数(使用 GNU 风格的内联汇编):

void escape(void* p)
{
    asm volatile("" : : "g"(p) : "memory");
}

void clobber()
{
    asm volatile("" : : : "memory");
}

它适用于任何支持 GNU 样式内联汇编的编译器(GCC、Clang、英特尔的编译器,可能还有其他编译器)。但是,他提到它在 MSVC 中不起作用。

检查 Google Benchmark's implementation ,似乎他们使用重新解释转换为 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
    

    Here is a link to code on GitHub.

    关于visual-c++ - MSVC 中的 "Escape"和 "Clobber"等效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33975479/

    相关文章:

    c++ - MFC 自定义 Tab 键事件处理程序

    使用集群的 Node.js 性能

    php - 我如何对我的 SQL 和 PHP 代码进行基准测试?

    java - 测量 GPRS 和 3G 带宽的正确方法

    java - JMH vs JMeter 用于基准测试 Java 类?

    Java并行流性能

    c++ - 是否可以在保持 RTTI 启用的情况下从可执行文件中删除类型名称?

    c++ - Winsock 接收缓冲区错误

    c++ - 将 Qt 与 WinForms 集成以使用某些类

    java - 如何用 Java 编写正确的微基准测试?