【发布时间】:2012-01-09 12:07:00
【问题描述】:
最近,我使用 DSPACK 组件对我在 Delphi 6 中的 DirectShow 应用程序进行了一些深入的计时检查。作为诊断的一部分,我创建了一个关键部分类,它为大多数 Windows 编程语言中常见的关键部分对象添加了超时功能。如果第一次Acquire()和最后一次匹配Release()之间的持续时间超过X毫秒,则抛出异常。
最初我将超时设置为 10 毫秒。我在关键部分中包装的代码非常快,主要使用内存移动和填充来完成保护区域中包含的大多数操作。令我惊讶的是,我在看似随机的代码部分中出现了相当频繁的超时。有时它发生在迭代缓冲区列表并按顺序执行某些快速操作的代码块中,有时发生在仅在 Acquire() 和 Release() 调用之间清除标志的受保护代码的一小部分中。我注意到的唯一模式是超时发生时发现的持续时间以大约 16 毫秒的中值为中心。显然,在我上面提到的后一个例子中设置标志需要很长时间。
所以我的问题是:
1) Windows 线程管理代码是否有可能在相当频繁的基础上(大约每几秒一次)切换出一个未阻塞的线程并且在 16 毫秒或更长时间内不返回它?
2) 如果这是一个合理的情况,我可以采取哪些措施来减少这种情况发生,我应该考虑提升我的线程优先级吗?
3) 如果这不是一个合理的场景,我还应该查看或尝试什么作为分析技术来诊断真正的问题?
注意:我在具有 3 GB 内存的 Intel i5 Quad Core 上运行 Windows XP。此外,我需要在此代码中快速的原因是由于我在 DirectShow 过滤器图中选择的缓冲区大小(以毫秒为单位)。为了将延迟保持在最低限度,我的图表中的音频缓冲区每 50 毫秒交付一次。因此,任何占用该时间大部分时间的操作都是麻烦的。
【问题讨论】:
-
你是如何测量时间的?
-
我正在检查系统时钟。在 Delphi 中,这就是“现在”功能。
-
这是一个开始的问题 - 这可能是系统时钟的粒度。
-
我不是总是会超时而不是有时吗?或者错误的数量是否浮动?在任何一种情况下,我还能使用什么?由于 CPU 速度步进,性能计数器似乎是一个真正的蛇坑,那么还有什么?
-
说实话,不确定。这很可能取决于 Windows 的版本。我很确定
Sleep的最小“有用”值为 15 毫秒。
标签: windows multithreading scheduled-tasks critical-section