首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Windows休眠时,CreateWaitableTimer在Xeon上的执行方式与i7处理器不同

使用Windows休眠时,CreateWaitableTimer在Xeon上的执行方式与i7处理器不同
EN

Stack Overflow用户
提问于 2020-06-09 02:08:11
回答 1查看 453关注 0票数 4

我正在做一个需要1ms睡眠的程序。为了产生长度~1ms的硬件脉冲,使用了睡眠。

我正在使用下面的代码来睡眠

代码语言:javascript
复制
void usleep(__int64 usec)
{
  HANDLE timer;
  LARGE_INTEGER ft;
  ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time

  timer = CreateWaitableTimer(NULL, TRUE, NULL);
  SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
  WaitForSingleObject(timer, INFINITE);
  CloseHandle(timer);
}

取自这里

当我在Intel i7上使用上面的代码(使用Embarcaderos i7编译器)时,通过1000 ( 1ms ),我就可以使用波科时间戳函数来测量睡眠时间,达到大约1ms。代码本身在线程中执行。

代码如下所示:

代码语言:javascript
复制
    mDebugFile <<  std::setprecision (17) << mPulseEventTime.elapsed()/1000.0 << "\t" << 0 << "\n";
    setHigh(false);
    mDebugFile <<  std::setprecision (17) << mPulseEventTime.elapsed()/1000.0 << "\t" << 1 << "\n";       
    usleep(1000);
    mDebugFile <<  std::setprecision (17) << mPulseEventTime.elapsed()/1000.0 << "\t" << 1 << "\n";
    setLow(false);
    mDebugFile <<  std::setprecision (17) << mPulseEventTime.elapsed()/1000.0 << "\t" << 0 << "\n";

其中mDebugFile是fstream对象,setLow/setHigh是对硬件的调用。

但是,当在上执行相同的代码( Xeon )时,睡眠量约为10 ms。假设Poco的定时函数给出了适当的时间,当要求1ms时,10 ms是相当大的。

还有其他方法可以让你在1ms内获得可靠的睡眠吗?可以修改Windows操作系统以提供更可靠的睡眠吗?

我无法访问boost或以上的C++11功能。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-11 17:23:03

Windows并不是一个实时的操作系统,因此在用户代码中获得超级精确的睡眠时间是永远无法保证的。有很多事情在起作用。

  • 操作系统可能会改变过期时间以节省电源。这叫做定时器合并。一次醒来来处理一些事件比更频繁地在更高频率上醒来更有效。如果操作系统对不同类型的硬件使用不同的策略,那就不足为奇了。
  • WaitForSingleObject (和相关的API)仍然受制于调度程序。当对象发出信号时,等待线程就可以用于调度,但这并不意味着它将立即被调度。它取决于进程和线程的优先级,可用的核心,系统的量子间隔,月亮的相位等。

在Windows上增加默认计时器解析的API有两个: NtSetTimerResolution (正式无文档)或timeBeginPeriod。如果机器没有超载,您可以使用基本方法(例如睡眠),在用户代码中获得接近1ms的间隔。

但是很多节目都是浪费能源滥用这些原料药。(如果你在一台机器上看到1毫秒的分辨率,很可能是因为某个程序已经提高了计时器分辨率。)长期以来,这一直被认为是不好的做法。定时器分辨率是一个系统范围的设置,因此它会影响机器上运行的一切.如果必须增加分辨率,请只在需要时这样做,并确保在完成后立即恢复默认值。

如果您需要更高的精度,我相信您需要做一个内核模式的驱动程序,但我没有这方面的经验。在某种程度上,Windows增加了一个音频堆栈,以保证延迟20 us或更少。如果我没记错的话,那就需要内核模式的恶作剧。

您可以考虑使用微控制器(例如,Arduino)来生成硬件信号,并让Windows程序通过串行接口向其发送命令。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62273909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档