为什么 std::future::wait_for 不等待正确的持续时间
Why does std::future::wait_for not wait for the correct duration?
我不明白为什么当指定的持续时间增加时,调用std::future::wait_for
时测量的持续时间和指定持续时间之间的差异会增加。
当我告诉std::future
等待 10ns 并测量经过的时间时,我得到 ~2000ns。现在,10ns 是一个非常短的持续时间,因此可能需要等待这么短的时间,相关函数调用涉及太多开销。但是当我告诉std::future
等待 100000ns 并测量经过的时间时,我得到 ~150000ns。分别等待 10 微秒和 100 微秒时可以看到类似的效果。
#include <chrono>
#include <future>
#include <iostream>
#include <thread>
using namespace std::chrono;
using namespace std::chrono_literals;
void f() { std::this_thread::sleep_for(1s); }
int main() {
steady_clock::time_point start, end;
std::future<void> future = std::async(std::launch::async, f);
start = steady_clock::now();
future.wait_for(10ns);
end = steady_clock::now();
std::cout << "10 -> " << (end - start).count() << 'n';
start = steady_clock::now();
future.wait_for(100000ns);
end = steady_clock::now();
std::cout << "100000 -> " << (end - start).count() << 'n';
return 0;
}
我用 g++ future_test.cpp -lpthread
编译上面的代码,在 Ubuntu 18.04 上使用 g++ 7.3.0。
我可以解释类似的东西
10 -> 2000
100000 -> 102000
但这不是我得到的。以下是多次执行的代表性结果:
10 -> 2193
100000 -> 154723
为什么 100'000ns 的测量持续时间比指定持续时间超过 ~2'000ns?
文档:
std::future_status wait_for( const std::chrono::duration& timeout_duration );
由于以下原因,此功能的阻塞时间可能会超过 timeout_duration 计划或资源争用延迟。
睡觉和等待只承诺至少等你问的时间。由于硬件和计划限制引入了不可预测的延迟,因此睡眠或等待可能持续多长时间没有固定的最大值。
对于周期性应用程序(如计时器(,如果您等到一个时间点,然后将该时间点增加固定量,则可以获得稳定的睡眠(平均(。如果继续这样做,只要线程唤醒的频率足够高,您将在一段时间内平均获得目标延迟。
4 GHz 时钟为每刻 0.25 秒。 10 ns 是 40 个即时报价,或 40 条指令给出或接受。
要求10 ns的延迟意味着任何事情都是非常荒谬的;计算当前时间所需的时间可能很容易超过10 ns。
所以你在这里测量的是:
start = steady_clock::now();
future.wait_for(10ns);
end = steady_clock::now();
std::cout << "10 -> " << (end - start).count() << 'n';
计算当前时间所需的时间,等待开销(检查它是否准备就绪等(。
在第二种情况下:
start = steady_clock::now();
future.wait_for(100000ns);
end = steady_clock::now();
std::cout << "100000 -> " << (end - start).count() << 'n';
相差约为 50,000 ns。 那是 1/20000 秒。
在这里,我们可能会做一些事情,例如将CPU置于低功耗模式,甚至设置旋转锁。
您可能正在切换上下文,但我猜不是;切换到另一个上下文然后再切换回来可能会花费太多时间在这里打扰。
交互式操作系统上的时间切片通常在 1/50 秒的数量级,或者当 CPU 中存在争用时,大约为 20000000ns。
您要求的是实时内容,这与系统非常相关。这是操作系统的工作。但即使你使用RTOS,或者preempt-RT或类似的东西,我也不确定C++stdlib是否可以获得这种准确性。
当您需要它时,如果系统可以为您提供它,则最好求助于依赖于操作系统的调用。
无论如何,在 1ms 精度的范围内,我通常会旋转。但请注意:您将有异常值。
- 从持续时间构造std::chrono::system_clock::time_point
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 时间持续时间到时间字符串
- 指向(数据)成员的指针作为非类型模板参数,例如具有自动存储持续时间/无链接
- 为什么具有静态存储持续时间的同一内联变量在包含在 VS2017 编译的两个翻译单元中时会构造和销毁两次
- 将毫秒转换为给定格式的持续时间
- 具有静态存储持续时间的常量初始化变量的初始化顺序
- 划分和乘以STD :: Chrono ::持续时间
- 静态存储持续时间初始化
- C++计划持续时间内(字体)资源的分配
- FFMPEG:具有不同持续时间的多路复用流
- 在不同翻译单元中具有静态存储持续时间的依赖非局部常量浮点变量的常量初始化
- 使用System_Clock :: TO_TIME_T警告持续时间_t
- 访问和存储/解析性std :: Chrono ::持续时间:: milliseconds(cpprest)时使用什么类型
- 我可以让QT到概要文件插槽执行持续时间吗?
- 在STD :: Chrono ::剩余时间测量的持续时间
- 自定义 AVIOContext 的未定义 AVFormatContext 持续时间
- 使用计时比较C++的持续时间/秒数并不像预期的那样工作
- 为什么 std::future::wait_for 不等待正确的持续时间
- C++ - 函数中的局部指针变量具有什么类型的存储持续时间以及它们存储在哪里?