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

时间:2014-10-11 09:20:05

标签: c# multithreading multiprocessing

  1. 硬件:我们使用24核(2 * 12核心)机器。 SSD磁盘和SAS-RAID 0磁盘有2个独立的控制器。操作系统:Windows 8.1。超线程已禁用。

  2. 软件:

    2.1。有一个主服务器为工作人员填写工作队列,然后从结果队列中收集结果。

    2.2。有 n - 工作人员从工作队列中检索工作。他们将小输入文件写入磁盘并启动外部进程以执行实际计算。在外部进程完成输出后,需要从文件系统读入大小为10-15 MB的文件并进行相应的解析。最后,worker将结果放在结果队列中,并继续处理工作队列中的下一个项目。

  3. 利用这两个磁盘对文件系统的访问在工作进程之间均匀分配。

  4. 观察

    4.1。从 0 - 10 工作人员来看,多线程和多处理几乎都是线性加速。从 10 增加到 28 工作人员,在多处理的情况下有一个合理但亚线性的加速,但在多线程的情况下几乎没有增加。

    4.2。我们为多线程做了大量的时间安排,发现计算的时间几乎保持不变,增加工人数量时增加的可忽略不计。 相反,当从 10 - 40 增加工作人员数量时,从磁盘读取文件的时间会急剧增加并导致核心进入空转。

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

  5. 最后一个问题:多线程的瓶颈是什么?我们如何规避它?

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

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

    更新2019年在具有18个核心和Windows 10的其他计算机上,我们观察到完全相同的行为。

2 个答案:

答案 0 :(得分:3)

Multiprocessing是否优于Multithreading,反之亦然,这在很大程度上取决于您正在使用的具体代码和您的环境,因此很难在没有看到的情况下完全确定正在发生的事情。有问题的实际代码和详细测量(响应时间,CPU,磁盘,内存性能计数器值等)。

从分析 4.2。 4.3。开始,您的CPU和IO似乎未得到正确使用。如果您正确地执行这两种操作,那么多处理和多线程方案之间的性能不应该有任何显着差异。 CPU空闲和增加读取时间可能表示代码中存在线程阻塞问题,这可能会影响可伸缩性和性能。

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

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

CLR线程池使用核心数作为默认线程池最小值,这意味着当您的应用使用< = 24个线程时,您不会有性能损失。但是,当您安排超过24个并发作业时,线程池将开始以固定间隔将线程注入线程池,以通过Min.Limit为任务提供服务。在.NET框架中< 4.0是每0.5秒1个线程的速率。在.NET 4.0+中有一个并发保持算法,但它仍然不是最优的。

答案 1 :(得分:3)

您是否尝试使用某些性能分析工具来发现瓶颈所在,而不是寻找通用指南?我发现,虽然我经常追踪我逻辑的相同区域,以发现我的线程逻辑在哪里,但是由于不同的因素会影响线程性能,因此问题经常会有所不同 - 这个问题&#39从来没有相同的故事两次(呃...通常)。

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

祝你好运!