多线程代码的硬盘 I/O
让 我们看下 I/O 对多线程代码的影响,以及多线程要求从硬盘读取数据时的最佳 I/O 策略。便于分析,本文作者根据 IJG 库创建了一个内部位图到 JPEG 代码,可利用其将一系列位图转化成 JPEG。下图显示了该应用的串行版本。"读取" 框是指以 64 KB 块大小读取位图文件(写 .JPG 文件时也是相同的块大小)。读/写时间占用了总运行时间的约 41%,而 BMP2JPEG 占用了约 59%。与读取文件(每个 BMP 文件都约为 10 MB)文件相比,输出 JPEG 相当小,因此大部分的读/写时间都被读取占用了。点击查看大图
在双核设备上执行多线程的一个方法就是分散成两个线程。一个线程可负责奇数的文件,而另一个线程负责偶数的文件,如下图所示:
另一种多线程的方式是,在单线程上执行缓冲读/写,然后在多线程上处理计算密集型转换操作:
最后一种方法是采用排队的 I/O。在所有读取请求排队处创建 I/O 完成端口,多线程则在完成端口等待读取请求完成。转换操作首先启动,完整的输出文件经过缓存,最终在一个线程中被写出。该方法提供了系统的负载平衡,以及轻松扩展线程数量的可能性。
下图所示为这些多线程方法的性能:
当 利用多线程实施来执行缓冲 I/O 和排队 I/O时,性能扩展了约 1.52 到 1.56 倍,但 I/O 操作仍在两个线程中执行时,性能不会扩展。性能表现不佳是由于竞争线程引起了硬盘颠簸。当两个线程都在运行,同时硬盘试图读取 64 KB 数据块时,会导致硬盘严重的寻道/旋转损耗。由于需响应两个线程中的请求,每次读取缓存块后都要重新定位读取磁头。这就导致了次佳的硬盘旋转,增加了总读 取时间,还掩盖了多线程的性能优势。如下能量图表明排序 I/O 提供了最佳的功率和性能优化:
No comments:
Post a Comment