【发布时间】:2014-10-11 09:20:04
【问题描述】:
硬件:我们使用 24 核(2*12 核)机器。 SSD 磁盘和 SAS-RAID 0 磁盘有 2 个单独的控制器。操作系统:Windows 8.1。超线程已禁用。
-
软件:
2.1。有一个 master 为工人填充一个工作队列,然后从一个结果队列中收集结果。
2.2。有 n 个从工作队列中检索工作的工作人员。他们将小型输入文件写入磁盘并启动外部进程以执行实际计算。在外部进程完成后,需要从文件系统中读取大小为 10-15 MB 的输出文件并进行相应的解析。最后,worker 将结果放入 result-queue 并继续处理工作队列中的下一项。
使用两个磁盘对文件系统的访问在工作进程之间平均分配。
-
观察
4.1。从 0 到 10 个工人,多线程和多处理几乎是线性加速。从 10 增加到 28 个工人,在多处理的情况下有一个合理但亚线性的加速,但在多线程的情况下几乎没有增加。 p>
4.2。我们对多线程进行了广泛的计时,发现计算时间几乎保持不变,随着工人数量的增加,计算时间的增加可以忽略不计。 相比之下,当工人的数量从 10 - 40 增加时,从磁盘读取文件的时间会急剧增加,并导致核心进入空转。
4.3。在多处理的情况下,工作人员似乎能够充分利用两个独立的文件 IO 通道(RAID 和 SSD)并且远远胜过多线程。
最后一个问题:在多线程的情况下,瓶颈是什么,我们该如何规避它?
注意 1: 完全避免文件系统访问不是一种选择,因为外部进程是第三方软件。
注意 2: 我知道这些 answers,但它们没有解决我的问题。
2019 年更新在具有 18 个内核和 Windows 10 的不同机器上,我们观察到完全相同的行为。
【问题讨论】:
-
许多可能性。如果您正在使用线程池(即任务或
QueueUserWorkItem,那么线程池的线程管理就会发挥作用。它将确定您可以运行多少并发线程。这是基于每个进程的。这将使多线程场景更慢。读取文件会变慢,因为磁盘 i/o 本质上是一个单线程任务。 -
@JimMischel 我不使用线程池。
标签: c# multithreading multiprocessing