我意识到这在很大程度上取决于所讨论的流程,但有经验法则吗?
假设我有一个名为的多线程程序progX
,它提供了一个命令行开关 ( --cpu
) 来控制它可以使用的 CPU 数量。progX --cpu 1
启动 40 个并行实例每个使用一个 CPU ( ) 还是启动单个实例并告诉它使用 40 个 CPU ( )更快progX --cpu 40
?
我意识到这在很大程度上取决于所讨论的流程,但有经验法则吗?
假设我有一个名为的多线程程序progX
,它提供了一个命令行开关 ( --cpu
) 来控制它可以使用的 CPU 数量。progX --cpu 1
启动 40 个并行实例每个使用一个 CPU ( ) 还是启动单个实例并告诉它使用 40 个 CPU ( )更快progX --cpu 40
?
一般规则是:在您的任务之间没有任何关系的情况下,多进程版本的性能将趋向于多线程版本之一(某些操作系统使用进程实现线程,因此性能将严格等效)。
您将支付更多来初始化您的流程,特别是如果您使用一些托管环境(例如 Java 或 .Net),但随着时间的推移,初始启动费用将变得可以忽略不计。
因此,如果您有小任务,差异可能会很大,但如果您在几个小时内运行任务,则差异可以忽略不计。
当您的线程之间有一些交互时,事情变得有趣:
共享数据:在进程之间共享内存比线程之间更复杂且成本更高
同步:同步进程太麻烦了,特别是如果您可以使用语言结构进行透明线程同步
性能不适合多进程,但还有其他很好的理由使用它,比如可靠性:如果你使用一些可能会破坏和崩溃进程的组件,如果你有一个多线程应用程序,失败将导致损失在您的所有任务中,而对于多进程应用程序,只有一个会失败。
很大程度上取决于操作系统,但通常线程比进程更轻量级(实际上每个进程至少由一个线程组成),因此通过启动一个具有 40 个线程的进程,您将减少压力(尤其是在内存消耗方面)系统上。
还要记住,线程与进程根本不同,因为它们在共享地址空间上运行。但是,如果他们相互交流,这无关紧要。
到目前为止,启动单个实例更快。线程是为此目的而创建的,它们比进程更轻。事实上的规则是:让操作系统来做调度和内存管理,除非你需要自己做脏活。这样你的代码会更简单、更干净。操作系统有一堆较低级别的工具来更有效地处理进程和内存。当然,这取决于操作系统,但这是现代操作系统的一般规则,至少是我使用的操作系统(Linux)。
最准确的答案是执行一项小任务,并使用各种设置为您的应用程序计时。您可以通过每个启动 N 个 M cpus 进程
#!/bin/bash
M=$1
N=$2
for ((i=0; i<$N; i++)) ; do ( echo $i && time progX --cpu $M & ) ; done
重要的时间是最后一个打印的时间(所有进程应该或多或少同时并行启动)。