Как известно, clock()
может показывать меньше или больше значения реального времени - оба случая показаны в следующих примерах 1 и 2.
Для высокоточных измерений времени в С++ 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
Результат на С++ 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
Результат на С++ MSVS 2013 v120 (Windows 7x64):
for-loop took:
highres = 1.49109 s
steady = 1.49109 s
clock() = 1.49 seconds
time() = 2.00 seconds
Резюме:
-
Когда поток спит, тогда
clock()
на g++ 4.9.2 не измеряет время, в отличие от других функций. -
Когда мы используем многопоточность с помощью OpenMP или используя
<thread>
(ссылка), тогдаclock()
в g++ 4.9.2 измеряет циклы CPU всех потоков.
Также в Windows MSVS 2013 clock()
в обоих случаях требуется измерение реального времени, но это не гарантирует, что clock()
измеряет то же самое на других платформах (в linux g++ равен 0 для сна и x-fold для многопоточность).
Исходя из этого, если std::chrono::high_resolution_clock::now();
измеряет требуемое реальное время в обоих случаях как на Windows MSVS 2013, так и на g++ 4.9.2, это гарантирует, что оно будет измерять реальное время высокого разрешения на всех других платформах и будет ли оно гарантировать стандарт С++ 11/14 ~