Tot*_*son 4 c++ windows time c++builder
我正在开发一个需要持续约 1 毫秒睡眠的程序。睡眠用于生成长度约为 1 毫秒的硬件脉冲。
我正在使用以下代码进行睡眠
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);
}
Run Code Online (Sandbox Code Playgroud)
取自这里
当我在 Intel i7 上使用上面的代码(使用 Embarcaderos bcc32 编译器)时,通过 1000 (1ms) 我得到一个睡眠,我使用Poco 的时间戳函数测量到大约 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";
Run Code Online (Sandbox Code Playgroud)
其中 mDebugFile 是一个 fstream 对象,而 setLow/setHigh 是对硬件的调用。
但是,当在Xeon CPU上执行相同的代码时,睡眠时间测量为大约10 毫秒。假设 Poco 的计时函数给出了合适的时间,10 ms 是相当大的,当要求 1ms 时。
有没有其他方法可以让可靠的睡眠持续约 1 毫秒?能否修改 Windows 操作系统以提供更可靠的睡眠?
我无权使用 boost 或更高版本的 C++11 功能。
Windows 不是实时操作系统,因此永远无法保证在用户代码中获得超精确的睡眠时间。有很多东西在玩。
操作系统可能会改变到期时间以节省电量。这称为计时器合并。为处理一些事件而唤醒一次比在更高频率下更频繁地唤醒更节能。如果操作系统对不同类型的硬件使用不同的策略,那就不足为奇了。
WaitForSingleObject(和相关 API)仍然受调度程序的约束。当对象发出信号时,等待线程可用于调度,但这并不意味着它会立即被调度。这取决于进程和线程优先级、可用内核、系统的量子间隔、月相等。
有两个 API 可以增加 Windows 上的默认计时器分辨率: NtSetTimerResolution (官方未记录)或timeBeginPeriod。如果机器没有过载,您可以使用基本方法(例如,睡眠)在用户代码中获得非常接近 1 毫秒的间隔。
但是很多程序在滥用这些 API 时会浪费能源。(如果您在机器上看到 1 毫秒的分辨率,很可能是因为某些程序已经提高了计时器分辨率。)长期以来,这一直被认为是不好的做法。计时器分辨率是系统范围的设置,因此它会影响机器上运行的所有内容。如果您必须提高分辨率,请仅在需要时才这样做,并确保在完成后立即恢复默认值。
如果您需要更高的精度,我相信您需要制作内核模式驱动程序,但我对此没有任何经验。在某些时候,Windows 添加了一个音频堆栈,以保证 20 us 或更少的延迟。如果我没记错的话,那需要内核模式的恶作剧。
您可能会考虑使用微控制器(例如,Arduino)来生成硬件信号,并让您的 Windows 程序通过串行接口向其发送命令。
| 归档时间: |
|
| 查看次数: |
213 次 |
| 最近记录: |