我可以精确计时重叠的 ReadFileEx 操作吗?
Posted
技术标签:
【中文标题】我可以精确计时重叠的 ReadFileEx 操作吗?【英文标题】:Can I precisely time overlapped ReadFileEx operations? 【发布时间】:2011-06-14 09:29:38 【问题描述】:我正在使用ReadFileEx(使用 CreateFile 和 FILE_FLAG_NO_BUFFERING 标志打开)从文件中读取扇区对齐的块,记录调用前的开始时间和完成例程中的结束时间(时间来自 QueryPerformanceCounter)。
无论整个文件的大小如何,我的块读取的大小都是恒定的。块偏移按顺序排列,因此 ReadFileEx 总是在文件中读取比最后一个点更远的点。我注意到一些奇怪的行为,例如较小的文件记录的块读取时间比较大的文件要快得多。
在这种情况下,较大文件的大小是较小文件的两倍 - 我不应该期望这在原始数据读取级别上很重要,因为无论如何我正在读取相同大小的块。我看到的是较小的文件报告读取速度为 160mb/s,而较大的文件报告读取速度为 110mb/s。
我仍在努力假设是我的代码中的其他东西导致了问题。我还希望读取操作在 ReadFileEx + GetLastError 返回 ERROR_IO_PENDING 后的某个操作系统定义点开始。
编辑:我的计时不准确已通过调整我的读取线程得到进一步确认,因此它有更多时间在警报状态下等待完成处理程序通知。这提高了报告的读取速度,表明我的部分问题是完成处理程序在读取完成后没有立即被调用(因此我的结束时间比它应该的晚)。但是,这样做会按比例提高较大和较小文件的报告速度。
TL;DR 我的问题是,我可以测量读取操作的实际时间,而不是调用 ReadFileEx 之间的时间(可能不会直接开始读取离开)和完成例程?
【问题讨论】:
只是为了澄清一下,您是在不等待完成的情况下拨打多个ReadFileEx
,还是每次完成都拨打一个ReadFileEx
?据我所知,没有简单的方法来计算实际阅读的时间。
@dauphic 我正在进行多个 ReadFileEx 调用,每个调用都在读取完成后的某个时间点调用完成处理程序。
对此我不是 100%,但我相信操作系统可能会决定同时执行多个读取。这可能会损坏对大文件的读取。我的经验是,重叠读取仅用于与处理最后一次读取并行执行下一次读取,而不是对多次读取进行排队。
@dauphic 你能解释一下它会如何损坏读取吗?
对不起,我的意思是读取性能。根据缓存的不同,磁头最终可能会跳来跳去,以服务并发读取请求。
【参考方案1】:
TL;DR 我的问题是,我可以测量 读操作的实际时间, 而不是通话之间的时间 ReadFileEx(它可能不会启动 立即阅读)和完成 例行公事?
可能不是来自用户模式代码。
您无法控制的变量太多。您不知道可能需要什么搜索(例如,一个文件可能是碎片化的,另一个可能不是)。文件映射(文件段到磁盘块)可能已经被缓存,也可能没有被缓存。即使没有读取缓冲区,仍然存在集群、驱动器上重新排序、驱动器上缓存等。通过异步操作,您还可以使用调度程序。
使用驱动器,您可以进行一些精确的测量,但您仍然需要进行大量实验并计算平均值以获得统计结果,以排除驱动器内部发生的所有奇怪事情(重试、重新排序、使用备件、板载缓存、区域位记录、热重新校准等)。
【讨论】:
以上是关于我可以精确计时重叠的 ReadFileEx 操作吗?的主要内容,如果未能解决你的问题,请参考以下文章
网络音频 api 计时是不是比 setTimeout 更精确