C++ 标准C++;11保证高分辨率时钟测量实时性(非CPU周期)?
众所周知,C++ 标准C++;11保证高分辨率时钟测量实时性(非CPU周期)?,c++,multithreading,performance,c++11,performance-testing,C++,Multithreading,Performance,C++11,Performance Testing,众所周知,clock()可能显示小于或大于实时值-以下示例1和2中显示了这两种情况 对于C++11中的高精度时间测量,我们可以使用: std::chrono::高分辨率时钟::现在()-保证高精度 std::chrono::staid_clock::now()-保证测量的实时性 clock()-保证高精度,但测量CPU周期而不是时间 时间(&t\u开始)-不是高精度,而是实时测量 1-例如: 结果:C++ MMSS 2013 V120(Windows 7x64): 2-第二个示例OpenMP
clock()
可能显示小于或大于实时值-以下示例1和2中显示了这两种情况
对于C++11中的高精度时间测量,我们可以使用:
std::chrono::高分辨率时钟::现在()代码>-保证高精度
std::chrono::staid_clock::now()代码>-保证测量的实时性
clock()代码>-保证高精度,但测量CPU周期而不是时间
时间(&t\u开始)代码>-不是高精度,而是实时测量
:
<>结果:C++ MMSS 2013 V120(Windows 7x64):
简历:
clock()
不会测量时间
()使用多线程时,g++4.9.2上的clock()
会测量所有线程的CPU周期clock()
测量所需的实时性,但这并不保证clock()
在其他平台上测量相同的时间(在linux上,g++的睡眠时间为0,多线程时间为x倍)
基于此,if
std::chrono::high_resolution_clock::now()
在Windows MSVS 2013和g++4.9.2上测量这两种情况下所需的实时性,这是否保证它将在所有其他平台上测量真实的高分辨率时间,是否保证标准C++11/14?该标准没有从其时钟中指定此行为。不完全是
时钟具有静态特性,可以检查。任何稳定的
返回true的时钟都不能是那种仅仅因为你让线程休眠而停止运行的时钟。然而,该值为false的时钟可能由于各种原因而不稳定。它可能不稳定,因为它是一个挂钟,如果系统时间改变,它就会改变。或者因为滴答声之间的周期是一个平均值,而不是一个精确的数字
所以,是稳定的
并不能真正回答你的问题
该标准没有规定
高分辨率时钟::是稳定的
,但它确实需要实现来回答这个问题。如果它是稳定的,那么你就可以保证睡眠线程不会停止时钟。但如果它不稳定。。。你根本得不到任何保证。简短回答:在C++14标准中,高分辨率时钟
没有明确提供你想要的保证。
目前,稳定时钟
和系统时钟
提供了更好、更明确的保证。然而,大多数实现可能会确保HRC在其线程处于休眠状态时进行。不过,最好还是自己做类型别名。请参阅下面的“编辑”部分和评论中的讨论
长答覆:
事实上,确实隐含地承认(在注释30.2.4“计时规范”,注释5中)时钟对象在其相关线程处于休眠状态时不需要前进。对于上下文,本节将解释标准库计时器对象是如何工作的;计时器的行为基于用于设置计时器的时钟的行为
[注:如果时钟与稳定时钟不同步,例如
CPU时钟,这些超时可能无法提供有用的功能。
-[完注]
请注意,在这种情况下,“超时可能不会提供有用的功能”意味着,如果使用未同步(非实时)时钟使用计时器在特定时钟时间之前睡眠,\u线程将不会唤醒。所以上面的注释有点轻描淡写
事实上,时钟规范(20.13.3)中没有任何内容需要与稳定时钟同步
然而,在20.13.7.3中的定义中,本标准似乎隐含了两个潜在的别名:
高分辨率时钟
可能是系统时钟
的同义词,或者
稳定的时钟
稳定\u时钟
当然是稳定的<代码>系统时钟为非,因为程序运行时系统时间可能会发生变化(例如,由于NTP更新)
但是,系统时钟(20.13.7.1)仍然是一个“实时”时钟:
类system\u clock
的对象表示从
全系统实时时钟
因此,当线程休眠时,系统时钟将不会停止前进。
这证实了Nicol Bolas的观点,即是稳定的
对于高分辨率时钟
可能是错误的,即使时钟的行为与您预期的一样(即,无论其关联线程的状态如何,它都会前进)
基于此,期望大多数主流实现为高分辨率时钟使用某种实时(即同步)时钟似乎是合理的。毕竟,实现是为了有用而设计的,如果时钟不是实时的,那么它通常就不那么有用,特别是如果按照上面关于“有用功能”的注释,它与计时器一起使用的话
但是,由于不能保证,您应该检查要使用的每个实现的行为和/或文档
编辑:我已经开始讨论这个问题,表明这是标准中的一个缺陷。霍华德·希南特(Howard Hinnant)的第一个回答值得一提,他因将其纳入标准而受到赞扬:
我不反对使用高分辨率时钟,因为
#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;
}
sleep(3) took:
highres = 3.00098 s
steady = 3.00098 s
clock() = 0.00 seconds
time() = 3.00 seconds
sleep(3) took:
highres = 3.00017 s
steady = 3.00017 s
clock() = 3.00 seconds
time() = 3.00 seconds
#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;
}
for-loop took:
highres = 0.213906 s
steady = 0.213905 s
clock() = 1.35 seconds
time() = 0.00 seconds
for-loop took:
highres = 1.49109 s
steady = 1.49109 s
clock() = 1.49 seconds
time() = 2.00 seconds
static_assert(
std::is_same<high_resolution_clock, steady_clock>::value
|| std::is_same<high_resolution_clock, system_clock>::value,
"high_resolution_clock IS NOT aliased to one of the other standard clocks!");
using maxres_sys_or_steady =
std::conditional<
system_clock::period::den <= steady_clock::period::den,
system_clock, steady_clock
>::type;
using maxres_nonsleeping_clock =
std::conditional<
high_resolution_clock::is_steady,
high_resolution_clock, maxres_sys_or_steady
>::type;