繁体   English   中英

使用多个线程进行硬盘争用

[英]Hard disk contention using multiple threads

我尚未对此进行任何配置文件测试,但是对于使用多线程与一个线程从硬盘加载资源的优点/缺点,普遍的共识是什么? 注意。 我不是在谈论主线程。

我本以为使用多个“其他”线程来进行加载是没有意义的,因为HD不能一次执行两项操作,因此肯定只会导致磁盘争用。

不知道在架构上走哪条路,不胜感激。

编辑:抱歉,我的意思是说SSD驱动器不是磁性驱动器。 两者对我来说都是高清的,但是我对具有单个SSD驱动器的系统更感兴趣。

如注释中所指出的,使用多个线程的一个优点是大文件加载不会延迟向线程加载器的接收者呈现较小的文件。 就我而言,这是一个很大的优势,因此即使这样做花费一点精力,还是需要多个线程。

我知道没有简单的答案,但是我要问的真正问题是,使并行磁盘顺序写入(在OS层中)而不允许只允许一个资源加载器线程,将会带来什么样的性能损失? 造成这种情况的因素是什么? 我的意思不是平台,制造商等。从技术上讲,OS / HD交互的哪些方面会影响这一惩罚? (理论上)。

进一步的编辑:我的确切用例是纹理加载线程,它们仅存在于从HD加载然后将它们“传递”到opengl,因此线程中的“计算”最少(可能是某种类型转换等)。线程将花费大部分时间等待HD(我想),因此了解OS-HD交互的管理方式非常重要,因为我的OS是Windows 10。

注意。 我不是在谈论主线程。

主线程与非主线程对磁盘读取速度的影响为零。

我本以为使用多个“其他”线程来进行加载是没有意义的,因为HD不能一次执行两项操作,因此肯定只会导致磁盘争用。

确实。 尝试进行的并行读取不仅被迫彼此等待(因此实际上不是并行的),而且还将使磁盘的访问模式变得随机,而不是顺序的,这由于磁盘磁头寻道时间而要慢得多。

当然,如果要处理多个硬盘,则每个驱动器专用的一个线程可能是最佳选择。


现在,如果您使用的是固态驱动器而不是硬盘驱动器,那么情况就不太清楚了。 多线程可能更快,更慢或相当。 可能涉及许多因素,例如固件,文件系统,操作系统,驱动器相对于其他瓶颈的速度等。


无论哪种情况,RAID都可能使此处所做的假设无效。

很多人会告诉您,HD不能一次完成一件事情。 这不是很正确,因为现代IO系统具有很多间接性。 用一个线程很难使它们饱和。

这是我在多线程IO的帮助下经历的三种情况。

  1. 有时,IO读取库的计算量非常小,可以考虑读取压缩视频,或者在传输发生后进行奇偶校验。 一个示例是使用具有多个线程的robocopy 启动具有128个线程的robocopy并不罕见!

  2. 设计了许多操作系统,以使单个进程无法使IO饱和,因为这会导致系统无响应。 在一种情况下,由于接近饱和IO,我的读取速度提高了3%。 如果存在某些系统策略来将数据分条到不同的驱动器(如在HPC群集中的Lustre驱动器上设置),则这是双重事实。 对于我的应用程序,最佳线程数是两个。

  3. 像RAID卡一样,更复杂的IO包含大量的缓存,可保持HD磁头不断读写。 为了获得最佳的吞吐率,您需要确保无论何时磁头旋转,它都会不断地进行读取/写入,而不仅仅是移动。 实际上,这样做的唯一方法是使卡的板载RAM饱和。

因此,很多时候,您可以使用多个线程来重叠少量的计算,而使用更大的磁盘阵列时,事情开始变得棘手。

不知道在架构上走哪条路,不胜感激。

确定每个线程的工作量是最常见的体系结构优化。 编写代码,以便轻松增加IO worker数量。 您将需要进行基准测试。

这取决于要处理的数据量。 这将确定应用程序是您绑定的I / O还是计算绑定的。

例如,如果您要对数据做的只是一些简单的算术,例如加1,那么最终将受I / O约束。 CPU可以将数据加1的速度远远快于任何I / O系统传递数据流的速度。

但是,如果您要对每批数据进行大量工作,例如FFT,过滤器,然后进行卷积(我在这里选择随机DSP例程名称),那么您很可能会结束受计算限制; CPU无法跟上拥有SSD的I / O子系统传递的数据。

判断仅应如何构造算法以匹配基础计算机的基础功能,这是一种艺术,反之亦然。 有诸如FTRACE / Kernelshark,Intel的VTune之类的性能分析工具,它们都可用于准确分析正在发生的事情。 Google会做很多工作来衡量其硬件完成的每瓦搜索数量,而功耗是最大的成本。

通常,任何类型的I / O,甚至包括大量SSD,都非常缓慢。 与CPU消耗的内存相比,即使PC(DDR4)中的主内存也非常缓慢。 与CPU内核相比,即使是L3和L2高速缓存也很慢。 很难正确地设计算法并对其进行多线程化,以使每个数据项都处于L1高速缓存中时在每个数据项上完成正确的工作量,以便L2,L3高速缓存,DDR4和I / O子系统可以交付下一个数据L1项会及时缓存,以保持CPU内核繁忙。 一台机器的理想软件设计可能在另一台具有不同CPU,SSD或内存SIMM的机器上绝望。 英特尔为实现良好的通用计算机性能而设计,实际上要从单个程序中获得最高性能是一个真正的挑战。 像英特尔的MKL和IPP这样的库在执行此操作方面有很大帮助。

一般指导

通常,应该根据任何特定线程安排所需的数据带宽来查看它,并研究这些线程正在执行的工作。

这意味着要对程序的内部处理循环进行基准测试,并测量程序处理了多少数据以及设法处理了多少数据,选择了一些有意义的数据项,但这些数据项比L3缓存的大小大得多。 单个“数据项”是输入数据量,相应的输出数据量以及用于处理输入到输出的所有变量,其总大小适合L1高速缓存(有一定的备用空间)。 绝不作弊-在适当的地方使用CPU SSE / AVX指令,不要通过编写纯C或不使用诸如Intel的IPP / MKL之类的方式来放弃它们。 [尽管有人正在使用IPP / MKL,但它会尽力为您完成所有这些工作。]

如今,只要您不对数据进行随机分散的访问,DDR4内存将适用于20至100GByte /秒之间的任何速度(取决于CPU,SIMM的数量等)。 通过使L3饱和,您将被DDR4速度所束缚。 然后,您可以开始更改代码,从而增加每个线程在单个数据项上完成的工作。 继续增加每个项目的工作量,速度最终将开始增加; 您已经达到了不再受DDR4,L3和L2速度限制的地步。

如果在此之后您仍然可以看到增加每个数据项工作量的方法,请继续。 最终,您将获得接近IO子系统带宽的数据带宽,只有这样,您才能从机器中获得最大的收益。

这是一个反复的过程,经验使人们可以简化它。

当然,如果某人对某件事的想法用光了,以增加每个数据项完成的工作,那么这就是设计过程的终点。 仅通过改善最终成为瓶颈的任何内容(几乎可以肯定是SSD)的带宽,才能实现更高的性能。

对于喜欢使用此软件的人来说,PS3的Cell处理器是一个梦想。 无需第二次猜测缓存,没有缓存。 一个人可以完全控制什么数据和代码在何处以及何时存在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM