性能问题:比较多线程和多处理的案例研究

Posted

技术标签:

【中文标题】性能问题:比较多线程和多处理的案例研究【英文标题】:Performance Issue: A case study comparing multi-threading versus multi-processing 【发布时间】: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。从 010 个工人,多线程和多处理几乎是线性加速。从 10 增加到 28 个工人,在多处理的情况下有一个合理但亚线性的加速,但在多线程的情况下几乎没有增加。 p>

    4.2。我们对多线程进行了广泛的计时,发现计算时间几乎保持不变,随着工人数量的增加,计算时间的增加可以忽略不计。 相比之下,当工人的数量从 10 - 40 增加时,从磁盘读取文件的时间会急剧增加,并导致核心进入空转。

    4.3。在多处理的情况下,工作人员似乎能够充分利用两个独立的文件 IO 通道(RAID 和 SSD)并且远远胜过多线程。

最后一个问题:在多线程的情况下,瓶颈是什么,我们该如何规避它?

注意 1: 完全避免文件系统访问不是一种选择,因为外部进程是第三方软件。

注意 2: 我知道这些 answers,但它们没有解决我的问题。

2019 年更新在具有 18 个内核和 Windows 10 的不同机器上,我们观察到完全相同的行为。

【问题讨论】:

许多可能性。如果您正在使用线程池(即任务或QueueUserWorkItem,那么线程池的线程管理就会发挥作用。它将确定您可以运行多少并发线程。这是基于每个进程的。这将使多线程场景更慢。读取文件会变慢,因为磁盘 i/o 本质上是一个单线程任务。 @JimMischel 我不使用线程池。 【参考方案1】:

Multiprocessing 是否比 Multithreading 具有优势,反之亦然,这在很大程度上取决于您正在使用的特定代码和您的环境,因此如果没有看到实际代码,就很难准确地得出结论和详细的测量(响应时间、CPU、磁盘、内存性能计数器值等)。

从您分析的 4.2.4.3. 点来看,您的 CPU 和 IO 似乎没有得到正确利用。如果您正确执行这两种情况,那么多处理和多线程方案之间的性能应该不会有任何显着差异。 CPU 空闲和读取时间增加可能表明代码中存在线程阻塞问题,这可能会影响可伸缩性和性能。

确保您没有阻塞同一进程内共享资源上的线程,这可能会影响多线程方案中的性能。此外,在处理队列和文件时,您应该利用非阻塞异步 IO 以确保最大。并发。

您应该记住,您的应用中并发工作线程的最佳数量是 24(每个内核一个线程),超过这个限制可能不是一个好主意,除非测量结果证明您错了。

CLR 线程池使用内核数作为默认线程池最小值,这意味着当您的应用使用

【讨论】:

【参考方案2】:

您是否尝试过使用一些分析工具来发现瓶颈所在,而不是寻找通用指南?我发现,虽然我经常追踪我的逻辑的相同区域以发现我的线程逻辑在哪里“卡顿”,但问题往往会有所不同,因为不同的因素会影响线程性能 - 它永远不会重复相同的故事(呃...通常)。

我强烈建议您使用像 dotTrace 这样的分析工具,以获得更深入的洞察力,并能够更深入地研究您的问题。

祝你好运!

【讨论】:

以上是关于性能问题:比较多线程和多处理的案例研究的主要内容,如果未能解决你的问题,请参考以下文章

多个平台的性能分析[关闭]

使用 Armadillo 和 OpenBLAS 进行多线程处理时性能不一致

系统性能常见问题

系统性能常见问题

可以通过多线程修复的低性能示例

python 测试CPU密集型任务的单进程,多线程和多进程性能