我正在使用轻线程运行并行算法,我想知道当系统提供多个内核和多个芯片时如何将这些分配给不同的内核。线程是否分配给单个芯片,直到芯片上的所有内核都用完?是否将线程分配给不同芯片上的内核以便更好地在芯片之间分配工作?
2 回答
您不会说您使用的是什么操作系统,但在 Linux 中,线程会根据该内核上的负载分配给该内核。准备好运行的线程将被分配给负载最低的核心,除非您通过设置线程亲缘关系另外指定。您可以使用sched_setaffinity()
. 有关更多详细信息,请参见手册页。一般来说,正如 meyes1979 所说,这是由您正在使用的操作系统中实现的调度程序决定的。
根据您使用的 Linux 版本,有两篇文章可能会有所帮助:这篇文章描述了早期的 2.6 内核,一直到 2.6.22,这篇文章描述了比 2.6.23 更新的内核。
不同的线程库执行不同的线程操作。如今, Linux 中的“标准”是NPTL,它将线程调度到与进程相同的级别。这很好,因为 Linux 上的进程创建速度很快,并且旨在始终保持快速。
Linux 内核试图为执行进程和线程提供非常强的 CPU 关联性,以增加缓存命中与缓存未命中的比率——如果一个任务总是在同一个内核上执行,它更有可能具有预先填充的缓存行。
这通常是一件好事,但我注意到内核可能并不总是将任务从繁忙的核心迁移到空闲的核心。这种行为可能会因版本而异,但我发现多个 CPU 绑定任务都在一个内核上运行,而其他三个内核处于空闲状态。(我发现其中一个核心比其他三个核心高出六七摄氏度。)
一般来说,正确的事情应该发生;但是当内核没有自动将任务迁移到其他处理器时,您可以使用该taskset(1)
命令来限制程序允许的处理器,或者您可以修改您的程序以使用该pthread_setaffinity_np(3)
功能来请求迁移单个线程。(这对于内部应用程序可能是最好的——您的一个用户可能不希望您的程序使用所有可用的内核。如果您确实选择在程序中包含对该函数的调用,请确保它可以通过配置文件进行配置提供与程序类似的功能taskset(1)
。)