多线程对 IO 密集型任务没有帮助?
Mulithreading does not help for IO intensive task?
我需要复制一组文件,每个文件的大小从1MB到700MB不等。复制每个文件后,我需要根据 md5sum.txt.
中的条目验证每个文件的校验和
我想优化这个任务,因此通过在多个线程之间分配负载来评估性能。结果并不如预期。本来以为复制和验证的时间会随着线程数的增加而减少,但实际花费的时间却增加了。
我修改了本link分享的ThreadPool源码,实现了线程池
可以在此处找到该应用程序的源代码
https://github.com/saai63/ThreadPool
不同线程数的结果如下所示,
根据我的阅读,可能的原因可能是所有任务现在都是 IO 绑定任务,因此所有线程都将在 IO 操作时被阻塞,因此不能 运行 作为共享资源并行是硬盘。我还了解到 HDD 控制器试图通过减少寻道时间来优化磁盘访问。磁盘喜欢顺序访问模式,任何并发访问都会破坏这种模式,从而导致大文件的延迟。
这是延迟的唯一原因还是还有其他一些因素?为什么时间会随着线程数的增加而增加?
IO 总是比 CPU 慢很多。当多个线程尝试从一个 IO 设备读取时,它们通常实现的是对设备的 "bull rush" 并增加 IO 操作的 "randomness",从而使其变慢。更少的线程有更大的机会进行顺序操作,这是众所周知的更快。
在多线程的情况下,您在线程之间共享 CPU。每当 运行 线程进入某种等待状态时,CPU 就会在线程之间切换。
这里你有 IO 绑定任务,没有必要让你的程序多线程,因为它们都将依赖单个 IO 设备。
即使你实现多进程解决方案(同一节点上的多个进程),所有进程都将等待相同的 IO 设备并且不会给予任何性能优化。
一种解决方案是使用具有同时多客户端访问支持的共享磁盘构建某种多节点解决方案。
使用这种方法,您可以将任务分配给多个节点,访问同一个磁盘并执行操作。
编辑:
我认为时间增加是因为操作系统为多个线程提供服务所花费的时间。
在线程之间切换 CPU 和 IO 设备需要随着线程数量的增加,上下文切换是计算密集型任务,并且在线程之间切换时会失去 IO/CPU 缓存性能.
我需要复制一组文件,每个文件的大小从1MB到700MB不等。复制每个文件后,我需要根据 md5sum.txt.
中的条目验证每个文件的校验和我想优化这个任务,因此通过在多个线程之间分配负载来评估性能。结果并不如预期。本来以为复制和验证的时间会随着线程数的增加而减少,但实际花费的时间却增加了。
我修改了本link分享的ThreadPool源码,实现了线程池
可以在此处找到该应用程序的源代码 https://github.com/saai63/ThreadPool
不同线程数的结果如下所示,
根据我的阅读,可能的原因可能是所有任务现在都是 IO 绑定任务,因此所有线程都将在 IO 操作时被阻塞,因此不能 运行 作为共享资源并行是硬盘。我还了解到 HDD 控制器试图通过减少寻道时间来优化磁盘访问。磁盘喜欢顺序访问模式,任何并发访问都会破坏这种模式,从而导致大文件的延迟。
这是延迟的唯一原因还是还有其他一些因素?为什么时间会随着线程数的增加而增加?
IO 总是比 CPU 慢很多。当多个线程尝试从一个 IO 设备读取时,它们通常实现的是对设备的 "bull rush" 并增加 IO 操作的 "randomness",从而使其变慢。更少的线程有更大的机会进行顺序操作,这是众所周知的更快。
在多线程的情况下,您在线程之间共享 CPU。每当 运行 线程进入某种等待状态时,CPU 就会在线程之间切换。
这里你有 IO 绑定任务,没有必要让你的程序多线程,因为它们都将依赖单个 IO 设备。
即使你实现多进程解决方案(同一节点上的多个进程),所有进程都将等待相同的 IO 设备并且不会给予任何性能优化。
一种解决方案是使用具有同时多客户端访问支持的共享磁盘构建某种多节点解决方案。
使用这种方法,您可以将任务分配给多个节点,访问同一个磁盘并执行操作。
编辑:
我认为时间增加是因为操作系统为多个线程提供服务所花费的时间。
在线程之间切换 CPU 和 IO 设备需要随着线程数量的增加,上下文切换是计算密集型任务,并且在线程之间切换时会失去 IO/CPU 缓存性能.