gpt4 book ai didi

c++ - 与 i7 处理器相比,使用 Windows API CreateWaitableTimer sleep 在 Xeon 上的执行方式不同

转载 作者:行者123 更新时间:2023-12-01 14:04:34 24 4
gpt4 key购买 nike

我正在开发一个需要持续约 1 毫秒 sleep 的程序。 sleep 用于生成长度约为 1 ms 的硬件脉冲。

我正在使用以下代码进行 sleep

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);
}

取自 here

当我在 Intel i7 上使用上述代码(使用 Embarcaderos bcc32 编译器)时,通过 1000 (1ms) 我得到了我使用 Poco's timestamp 测量的 sleep 。功能约1ms。代码本身在线程中执行。

代码如下所示:
    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 是对硬件的调用。

但是,当在 上执行相同的代码时至强 CPU , sleep 被测量到大约 10 毫秒 .
假设 Poco 的计时函数给出了适当的时间,当要求 1ms 时,10ms 是相当大的。

有没有其他方法可以获得可靠的 sleep 约 1 毫秒?是否可以修改 Windows 操作系统以提供更可靠的 sleep ?

我无权使用 boost 或更高版本的 C++11 功能。

最佳答案

Windows 不是实时操作系统,因此无法保证在用户代码中获得超精确的 sleep 时间。有很多东西在玩。

  • 操作系统可能会改变到期时间以节省电量。这称为 timer coalescing .唤醒一次以处理一些事件比在更高频率下更频繁地唤醒更省电。如果操作系统对不同类型的硬件使用不同的策略,那就不足为奇了。
  • WaitForSingleObject(和相关的 API)仍然受调度器的约束。当对象发出信号时,等待线程可用于调度,但这并不意味着它将立即被调度。这取决于进程和线程优先级、可用内核、系统的量子间隔、月相等。

  • 有两个 API 可以提高 Windows 上的默认计时器分辨率:NtSetTimerResolution(官方未记录)或 timeBeginPeriod .如果机器没有过载,您可以使用基本方法(例如, sleep )在用户代码中获得非常接近 1 毫秒的间隔。

    但是很多程序 waste energy abusing these APIs . (如果您在机器上看到 1 毫秒的分辨率,很可能是因为某些程序已经提高了计时器的分辨率。)这一直被认为是不好的做法。计时器分辨率是系统范围的设置,因此它会影响机器上运行的所有内容。如果您必须提高分辨率,请仅在需要时这样做,并确保在完成后立即恢复默认值。

    如果您需要更高的精度,我相信您需要制作内核模式驱动程序,但我对此没有任何经验。在某些时候,Windows 添加了一个音频堆栈,可以保证 20 us 或更少的延迟。如果我没记错的话,那需要内核模式的恶作剧。

    您可能会考虑使用微 Controller (例如 Arduino)来生成硬件信号并让您的 Windows 程序通过串行接口(interface)向其发送命令。

    关于c++ - 与 i7 处理器相比,使用 Windows API CreateWaitableTimer sleep 在 Xeon 上的执行方式不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62273909/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com