std :: this_thread :: sleep_for()和纳秒

问题描述 投票:11回答:2

如果我并排放两个电话来确定最小的可测量持续时间:

// g++ -std=c++11 -O3 -Wall test.cpp
#include <chrono>
typedef std::chrono::high_resolution_clock hrc;

hrc::time_point start = hrc::now();
hrc::time_point end   = hrc::now();
std::chrono::nanoseconds duration = end - start;
std::cout << "duration: " << duration.count() << " ns" << std::endl;

我已经在循环中运行了数千次,并且在我特定的3.40GHz桌面上我一直得到40 ns +/- 2 ns。

但是,当我想看看我能睡到的最短时间时:

#include <thread>

hrc::time_point start = hrc::now();
std::this_thread::sleep_for( std::chrono::nanoseconds(1) );
hrc::time_point end   = hrc::now();
std::chrono::nanoseconds duration = end - start;
std::cout << "slept for: " << duration.count() << " ns" << std::endl;

这告诉我,我平均睡眠55400纳秒,或55.4微秒。远远超过我的预期。

把上面的代码放到for()循环中,我试着睡不同的数量,这就是结果:

  • sleep_for(4000 ns)=>睡眠58000 ns
  • sleep_for(3000 ns)=>睡眠57000 ns
  • sleep_for(2000 ns)=>睡眠时间为56000 ns
  • sleep_for(1000 ns)=>睡眠55000 ns
  • sleep_for(0 ns)=>睡眠54000 ns
  • sleep_for(-1000 ns)=>睡眠时间为313 ns
  • sleep_for(-2000 ns)=>睡眠时间为203 ns
  • sleep_for(-3000 ns)=>睡眠时间为215 ns
  • sleep_for(-4000 ns)=>睡眠时间为221 ns

我有一些问题:

  • 有什么可以解释这些数字?
  • 为什么在负时间内睡眠会返回200+ ns,而睡眠时间为0+纳秒会导致50,000+纳秒?
  • 负数作为睡眠时间是记录/支持的功能,还是我不小心偶然发现了一些我不能依赖的奇怪错误?
  • 是否有更好的C ++睡眠调用可以让我更加一致/可预测的睡眠时间?
c++11 g++ thread-sleep
2个回答
12
投票

有什么可以解释这些数字?

有一个非常明显的模式,你的所有结果都比你要求睡觉的时间长54000ns。如果你看看GCC的this_thread::sleep_for()是如何在GNU / Linux上实现的,你会看到它只使用nanospleep,正如Cubbi的评论所说,调用该函数可能需要大约50000ns。我猜一些成本就是进行系统调用,因此从用户空间切换到内核并返回。

为什么在负时间内睡眠会返回200+ ns,而睡眠时间为0+纳秒会导致50,000+纳秒?

猜测我会说C库会检查负数并且不会进行系统调用。

负数作为睡眠时间是记录/支持的功能,还是我不小心偶然发现了一些我不能依赖的奇怪错误?

标准不禁止传递否定参数,因此允许它,并且函数应该“立即”返回,因为相对超时指定的时间已经过去了。你不能依赖负参数返回比非负参数更快,这是你特定实现的一个人工制品。

是否有更好的C ++睡眠调用可以让我更加一致/可预测的睡眠时间?

我不这么认为 - 如果我知道一个,那么我们将在GCC中使用它来实现this_thread::sleep_for()

编辑:在更新版本的GCC的libstdc ++中我添加了:

if (__rtime <= __rtime.zero())
  return;

因此,当请求零或负持续时间时,将不会有系统调用。


0
投票

在struct task_struct中的内核init / init_task.c中定义了init_task的param

.timer_slack_ns = 50000, /* 50 usec default slack */

它添加到hrtimer_nanosleep()内核函数中的非RT进程中,以减少计时器的hardirqs次数。

© www.soinside.com 2019 - 2024. All rights reserved.