【发布时间】:2016-11-10 03:48:40
【问题描述】:
众所周知,clock() 可能会显示小于或大于实时值 - 这两种情况都显示在以下示例 1 和示例 2 中。
对于 C++11 中时间的高精度测量,我们可以使用:
-
std::chrono::high_resolution_clock::now();- 保证高精度 -
std::chrono::steady_clock::now();- 保证实时测量 -
clock();- 保证高精度,但测量 CPU 周期而不是时间 -
time(&t_start);- 不是高精度,而是实时测量
1- 例如:http://ideone.com/SudWTM
#include <stdio.h>
#include <time.h>
#include <thread>
#include <iostream>
#include <chrono>
int main(void) {
std::cout << "sleep(3) took: \n\n";
clock_t c_start, c_end;
time_t t_start, t_end;
std::chrono::high_resolution_clock::time_point h_start, h_end;
std::chrono::steady_clock::time_point steady_start, steady_end;
time(&t_start); // less precise than clock() but always get the real actual time
c_start = clock(); // clock() get only CPU-time, it can be more than real or less - sleep(3); took 0.00 seconds
h_start = std::chrono::high_resolution_clock::now();
steady_start = std::chrono::steady_clock::now();
std::this_thread::sleep_for(std::chrono::seconds(3));
steady_end = std::chrono::steady_clock::now();
h_end = std::chrono::high_resolution_clock::now();
c_end = clock();
time(&t_end);
std::cout << "highres = " << std::chrono::duration<double>(h_end - h_start).count() << " s \n";
std::cout << "steady = " << std::chrono::duration<double>(steady_end - steady_start).count() << " s \n";
printf("clock() = %.2lf seconds \n", (c_end - c_start) / (double)CLOCKS_PER_SEC);
printf("time() = %.2lf seconds \n", difftime(t_end, t_start));
return 0;
}
g++ (Debian 4.9.2-10) 4.9.2 上的结果:clock() = 0.00 秒
sleep(3) took:
highres = 3.00098 s
steady = 3.00098 s
clock() = 0.00 seconds
time() = 3.00 seconds
在 C++ MSVS 2013 v120 (Windows 7x64) 上的结果:
sleep(3) took:
highres = 3.00017 s
steady = 3.00017 s
clock() = 3.00 seconds
time() = 3.00 seconds
2- 第二个示例 OpenMP 或 <thread>:http://coliru.stacked-crooked.com/a/2922c85385d197e1
#include <stdio.h>
#include <time.h>
#include <thread>
#include <iostream>
#include <chrono>
#include <vector>
int main(void) {
std::cout << "for-loop took: \n\n";
clock_t c_start, c_end;
time_t t_start, t_end;
std::chrono::high_resolution_clock::time_point h_start, h_end;
std::chrono::steady_clock::time_point steady_start, steady_end;
time(&t_start); // less precise than clock() but always get the real actual time
c_start = clock(); // clock() get only CPU-time, it can be more than real or less - sleep(3); took 0.00 seconds
h_start = std::chrono::high_resolution_clock::now();
steady_start = std::chrono::steady_clock::now();
#pragma omp parallel num_threads(10)
{
for (volatile int i = 0; i < 200000000; ++i);
}
steady_end = std::chrono::steady_clock::now();
h_end = std::chrono::high_resolution_clock::now();
c_end = clock();
time(&t_end);
std::cout << "highres = " << std::chrono::duration<double>(h_end - h_start).count() << " s \n";
std::cout << "steady = " << std::chrono::duration<double>(steady_end - steady_start).count() << " s \n";
printf("clock() = %.2lf seconds \n", (c_end - c_start) / (double)CLOCKS_PER_SEC);
printf("time() = %.2lf seconds \n", difftime(t_end, t_start));
int b = getchar();
return 0;
}
g++ (Debian 4.9.2-10) 4.9.2 上的结果:clock() = 1.35 秒
for-loop took:
highres = 0.213906 s
steady = 0.213905 s
clock() = 1.35 seconds
time() = 0.00 seconds
在 C++ MSVS 2013 v120 (Windows 7x64) 上的结果:
for-loop took:
highres = 1.49109 s
steady = 1.49109 s
clock() = 1.49 seconds
time() = 2.00 seconds
简历:
当线程休眠时,g++ 4.9.2 上的
clock()不像其他函数那样测量时间。当我们通过 OpenMP 或
<thread>(link) 使用多线程时,g++ 4.9.2 上的clock()会测量所有线程的 CPU 周期。
同样在 Windows MSVS 2013 clock() 在这两种情况下都需要实时测量,但这并不能保证 clock() 在其他平台上测量相同(在 linux 上,g++ 为 0 表示睡眠,x-fold 表示多线程)。
基于此,如果std::chrono::high_resolution_clock::now(); 在 Windows MSVS 2013 和 g++ 4.9.2 两种情况下都需要实时测量,这是否保证它会在所有其他平台上测量真正的高分辨率时间,是否保证标准C++11/14?
【问题讨论】:
-
MSVC 2012 和 MSVC 2013 有一个
std::chrono::high_resolution_clock的已知错误,它使用系统时间,因此它只有 1 毫秒的分辨率。这已在 MSVC 2015 中修复。
标签: c++ multithreading performance c++11 performance-testing