多任务处理时的最佳线程数

the*_*eGD 5 multi-core multi-threaded parallel-processing

我知道有人问过类似的问题,但我认为我的情况有点不同。

假设我有一台带有 Linux 操作系统的 8 核和无限内存的计算机。

我有一个名为 Gaussian 的计算软件,它可以利用多线程。因此,我将其线程数设置为 8,以便进行最大速度的单次计算。但是,当我需要同时运行 8 个计算时,我真的无法决定该怎么做。在这种情况下,我应该将每个作业的线程数设置为 1(在 8 个进程中产生的总共 8 个线程)还是保持为 8(在 8 个进程中产生的总共 64 个线程)?真的很重要吗?一个相关的问题是操作系统是否会自动为每个线程执行不同内核的内核停放?

编辑:我知道基准测试是最好的了解方式。问题是,电脑是我大学的,所以他们一直很忙。换句话说,它的工作量对我来说以一种无法控制的方式变化,因为其他人也在使用这些计算机进行计算,因此无法进行实验。此外,该软件非常昂贵(1500 美元左右)并且每台计算机都获得许可,因此我不能简单地在我的个人计算机上运行基准测试...

小智 6

正确的数字取决于进程在 IO 上阻塞的时间。

“JVM 上的编程并发”一书对此有一些很好的信息:

“确定线程数”。对于一个大问题,我们希望线程数至少与可用内核的数量一样多。这将确保尽可能多的进程可用内核用于解决我们的问题......

所以最小线程数等于可用内核数。如果所有任务都是计算密集型的,那么这就是我们所需要的。在这种情况下,拥有更多线程实际上会受到伤害,因为当仍有工作要做时,内核将在线程之间进行上下文切换。如果任务是 IO 密集型的,那么我们应该有更多的线程。

当任务执行 IO 操作时,其线程会被阻塞。处理器立即上下文切换以运行其他符合条件的线程。如果我们只有与可用内核数量一样多的线程,即使我们有任务要执行,它们也无法运行,因为我们没有将它们安排在线程上供处理器接收。

如果任务有 50% 的时间被阻塞,则线程数应该是可用内核数的两倍。如果它们被阻塞的时间更少——也就是说,它们是计算密集型的——那么我们应该有更少的线程,但不少于内核数。如果它们花更多的时间被阻塞——也就是说,它们是 IO 密集型的——那么我们应该有更多的线程,特别是内核数的几倍。

所以我们可以计算我们需要的线程总数,如下所示:

线程数 = 可用内核数 /(1 - 阻塞系数)

如果您需要同时运行多个计算,也许可以看看是否可以在一个进程中使用适当大小的线程池运行它们。

否则,如果您有用于一次计算的最佳线程数,但一次运行 8 个,则可能有太多线程。

最好的解决方案是通过实验对其进行基准测试。

我不太确定您所说的核心停放是什么意思,但是由于缓存的原因,CPU 会倾向于在给定的核心上继续运行相同的线程,尽管有时也会由于不同的热/功率原因移动它。您可以使用 htop 之类的工具对此进行调查。


小智 5

理想情况下,所有作业的总线程数应该是系统的内核数,但在支持超线程的系统上,它应该是内核数的两倍。因此,如果系统没有超线程,则有 8 个计算在运行,每个计算应在一个线程中运行。

许多英特尔处理器都带有超线程,因此每个内核可以支持两个线程。例如,一个支持超线程的 8 核系统应该有 16 个线程才能充分利用系统。