【问题标题】:Looking for benchmarking code snippet (c++)寻找基准测试代码片段 (c++)
【发布时间】:2010-10-03 17:55:44
【问题描述】:

我的程序中的一些加载例程需要很长时间才能完成。我想要一个快速的小 sn-p 来检查函数执行所需的时间。小我的意思是“最好没有 3rd 方库”。

也许像占用系统时间一样简单?

start = current_system_time()
load_something()
delta = current_system_time()-start
log_debug("load took "+delta)

编辑:有问题的目标操作系统是 Windows。

【问题讨论】:

  • 这不会得到任何答案,因为“是”太短而无法发布。
  • 我希望得到一个“是”,然后是一个“但更清洁/更好的想法是......”

标签: c++ windows time benchmarking


【解决方案1】:

这是一种对 C/C++ 代码块进行计时的快速而肮脏的方法。你需要#include <sys/time.h>,应该是标准头...

struct timeval start, end;
gettimeofday(&start, NULL);
// benchmark code
gettimeofday(&end, NULL);
long long time =   (end.tv_sec * (unsigned int)1e6 +   end.tv_usec) - 
                 (start.tv_sec * (unsigned int)1e6 + start.tv_usec);

这应该在现代 Linux 系统上提供 1-2µs 的分辨率(您使用的是什么操作系统?),这意味着它不太适合学习小于 10µs 的项目。但是,您似乎并不处于那种情况。

更新:基于指定的操作系统...Windows implementation of gettimeofday()

【讨论】:

    【解决方案2】:

    你的回答:是的

    警告:不会在多线程代码或多核机器中工作,您需要一个强大的挂钟计时器。 所以我推荐你使用 omp 的挂钟。 OMP 包含在 VC 和 GCC 中,大多数编译器和它的标准你不必担心会消失

    #include <omp.h>
    
    // Starting the time measurement
    double start = omp_get_wtime();
    // Computations to be measured
    ...
    // Measuring the elapsed time
    double end = omp_get_wtime();
    // Time calculation (in seconds)
    

    【讨论】:

    • 确保链接到-lgomp
    【解决方案3】:
    #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
    
    namespace win32 {
        #include <windows.h>
    }
    
    class timer
    {
        win32::LARGE_INTEGER start_time_;
    public:
        timer() { QueryPerformanceCounter( &start_time_ ); }
        void   restart() { QueryPerformanceCounter( &start_time_ ); }
        double elapsed() const
        {
            win32::LARGE_INTEGER end_time, frequency;
            QueryPerformanceCounter( &end_time );
            QueryPerformanceFrequency( &frequency );
            return double( end_time.QuadPart - start_time_.QuadPart )
                / frequency.QuadPart;
        }
    };
    
    #else
    
    #include <ctime>
    
    class timer
    {
        clock_t _start_time;
    public:
        timer() { _start_time = clock(); }
        void   restart() { _start_time = clock(); }
        double elapsed() const
        {
            return double(clock() - _start_time) / CLOCKS_PER_SEC;
        }
    };
    
    #endif
    
    template< typename Func >
    double measure_time( Func f )
    {
        timer t;
        f();
        return t.elapsed();
    }
    

    【讨论】:

      【解决方案4】:

      我为此使用了一个类,它旨在测量执行函数所需的时间并将其写入 uth-16le 文本文件(我需要更新它以使用我为此创建的新类...但是纳米)。

      在函数顶部创建一个新实例,例如jProfiler(L"myFunction") 和函数末尾的清理将完成其余的工作,如果您想确定是新的并自己删除它。对于一个小测试来说有点矫枉过正,但可能会有所帮助:

      // start header
      
      /* jProfiler class by Semi Essessi
       *
       * (class description goes here)
       *
       */
      
      #ifndef __JPROFILER_H
      #define __JPROFILER_H
      
      #include <stdio.h>
      #include <windows.h>
      
      class jProfiler
      {
      private:
          wchar_t*        str;
          LARGE_INTEGER   start;
          LARGE_INTEGER   tps;
          LARGE_INTEGER   buf;
      
          static FILE*    f;
          static int      instCount;
      
          static void     Initialise();
          static void     Shutdown();
      public:
          jProfiler(const wchar_t* msg);
          ~jProfiler();
      };
      
      #endif
      
      // - end header
      
      /* jProfiler class by Semi Essessi
       *
       * (class description goes here)
       *
       */
      
      #include "jProfiler.h"
      
      #include <windows.h>
      
      FILE* jProfiler::f = 0;
      int jProfiler::instCount = 0;
      
      jProfiler::jProfiler(const wchar_t* msg)
      {
          // constructor code for menuVar
          int i = (int)wcslen(msg)+1;
          str = new wchar_t[i];
          memcpy(str, msg, sizeof(wchar_t)*i);
          str[i-1] =  0;
      
          QueryPerformanceFrequency(&tps);
          QueryPerformanceCounter(&start);
      
          instCount++;
          Initialise();
      }
      
      jProfiler::~jProfiler()
      {
          // destructor code for menuVar
          QueryPerformanceCounter(&buf);
          // work out change in time
          double dt=((float)buf.QuadPart - (float)start.QuadPart)/(float)tps.QuadPart;
          fwprintf(f, L"%s : %.20f\r\n", str, dt);
      
          if(str) delete[] str;
          instCount--;
          Shutdown();
      }
      
      void jProfiler::Initialise()
      {
          if(!f)
          {
              f = _wfopen(L"profilerlog.txt", L"wb");
              unsigned short a = 0xFEFF;
              fwrite(&a, sizeof(unsigned short), 1, f);
          }
      }
      
      void jProfiler::Shutdown()
      {
          if(instCount==0) if(f) fclose(f);
      }
      

      【讨论】:

        【解决方案5】:

        我的 sweet.hpp 库中有一个 benchmark.hpp 标头。它有两个基准测试工具。第一个是简单的手动启停计时

        Bench b;
        ...
        b.stop();
        b.milli(); // returns an uint with passed millisec. Also has sec and micro sec
        

        另一个更复杂一些。你可以像这样编写函数或块语句。

        void myFunc() {
            BENCH(someName);
            ...
        }
        

        最后致电sweet::Benchmark::printResults(); 以打印所花费的时间和通话次数。

        编辑: 我添加了一个函数,所以你可以这样调用它。

        double c = BENCHMARK_CNT(25, yourFunctionCallHere());
        

        【讨论】:

          猜你喜欢
          • 2012-05-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-21
          相关资源
          最近更新 更多