【问题标题】:precise time measurement精确的时间测量
【发布时间】:2012-12-29 12:35:26
【问题描述】:

我在 C++ 中使用 time.h 来测量函数的时间。

clock_t t = clock();
someFunction();
printf("\nTime taken: %.4fs\n", (float)(clock() - t)/CLOCKS_PER_SEC);

但是,我总是将时间设为 0.0000。分开打印时,clock() 和 t 具有相同的值。我想知道是否有办法在 C++ 中精确测量时间(可能是纳秒级)。我用的是VS2010。

【问题讨论】:

标签: c++ visual-studio-2010 chrono ctime


【解决方案1】:

C++11 引入了chrono API,可以用来获取纳秒:

auto begin = std::chrono::high_resolution_clock::now();

// code to benchmark

auto end = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(end-begin).count() << "ns" << std::endl;

对于更相关的值,最好多次运行该函数并计算平均值:

auto begin = std::chrono::high_resolution_clock::now();
uint32_t iterations = 10000;
for(uint32_t i = 0; i < iterations; ++i)
{
    // code to benchmark
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end-begin).count();
std::cout << duration << "ns total, average : " << duration / iterations << "ns." << std::endl;

但请记住 for 循环并分配 beginend var 也会占用一些 CPU 时间。

【讨论】:

  • 当您仅针对 Windows 时,QueryPerformanceFrequency 仍然是更好的选择。事实上,high_resolution_clockunder VS11 和 VS12 只是 system_clock 上的一个 typdef,它提供了平庸的分辨率。最近仅在 VS14 中修复了此问题。 connect.microsoft.com/VisualStudio/feedback/details/719443/…
  • high_resolution_clock 保证是单调的或稳定的。它可以在系统同步时间 (NTP)、闰秒或增量调整时来回跳转。如果要测量经过的时间,请使用 stable_clock
【解决方案2】:

我通常使用QueryPerformanceCounter函数。

示例:

LARGE_INTEGER frequency;        // ticks per second
LARGE_INTEGER t1, t2;           // ticks
double elapsedTime;

// get ticks per second
QueryPerformanceFrequency(&frequency);

// start timer
QueryPerformanceCounter(&t1);

// do something
...

// stop timer
QueryPerformanceCounter(&t2);

// compute and print the elapsed time in millisec
elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;

【讨论】:

    【解决方案3】:

    以下我完全同意的文字引用自Optimizing software in C++(任何 C++ 程序员的好读物)-

    如果时间测量可能需要非常高的分辨率 间隔很短。在 Windows 中,您可以使用 GetTickCountQueryPerformanceCounter 函数用于毫秒分辨率。一个多 使用时间戳计数器可以获得更高的分辨率 CPU,以 CPU 时钟频率计数。

    有一个问题是“时钟频率可能会动态变化,并且 由于中断和任务切换,测量结果不稳定。”

    【讨论】:

      【解决方案4】:

      在 C 或 C++ 中,我通常如下所示。如果仍然失败,您可以考虑使用 rtdsc 函数

            struct timeval time;
            gettimeofday(&time, NULL); // Start Time
      
            long totalTime = (time.tv_sec * 1000) + (time.tv_usec / 1000);
      
                //........ call your functions here
      
              gettimeofday(&time, NULL);  //END-TIME
      
              totalTime = (((time.tv_sec * 1000) + (time.tv_usec / 1000)) - totalTime);
      

      【讨论】:

      • x += y - x 没有意义,它相当于 x = y 在你的情况下会丢弃旧值
      • 是的,应该是totalTime = (...) - totalTime; 来计算第一次和第二次调用gettimeofday 之间的差异。 += 是错误的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-01
      • 2019-03-28
      • 2018-03-17
      • 1970-01-01
      • 2019-10-18
      • 2019-01-09
      相关资源
      最近更新 更多