强制 Linux 在共享 CPU 缓存的 CPU 个核心上安排进程
Force Linux to schedule processes on CPU cores that share CPU cache
现代 AMD CPU 由多个 CCX 组成。每个 CCX 都有一个 .
可以 set process affinity 将进程限制为某些 CPU 个核心。
有没有办法强制Linux在共享 L3 缓存的两个内核上调度两个进程(父进程线程和子进程),但仍然让调度程序自由选择哪个两个核心?
进程的底层库函数支持设置CPU set masks,它允许您定义一组核心,在这些核心上进程可以运行。有 pthreads 的等价物。参见 this man page and this command line tool。
This 是一篇关于 Linux 如何处理 NUMA 系统的非常有趣的文章。它基本上试图将代码和内存保持在一起,所以它已经 pre-disposed 开箱即用地做你想做的事。虽然我认为如果两个进程之间的交互是通过例如一个分配的共享内存而另一个最终只是“访问”(即在启动第二个进程时,内核不知道它会访问由一个单独的进程分配的内存,它实际上放在一个很远的核心上[用 NUMA 术语])。
我认为 CPU sets 显示了一些希望。在该页面的底部有将 shell 放入特定 CPU 集合的示例。这可能是一种方式,任何从 shell 开始的后续进程都将保留在相同的 CPU 集合中,而您不必为它们专门设置核心亲和力(我认为它们将从shell)。您仍然会根据集合中有哪些 CPU 来定义 CPU 集合,但只定义一次。
如果您手动选择一个 CCX,您可以为它们提供相同的亲和力掩码,使它们可以在该 CCX 中的任何核心上进行调度。
亲和掩码可以设置多个位。
我不知道有什么方法可以让内核决定哪个 CCX,然后将这两个任务安排到其中的内核。如果父级检查它当前 运行 在哪个核心上,它可以设置一个掩码以包括包含它的 CCX 中的所有核心,假设您有一种方法来检测核心 #s 是如何分组的,并且有一个函数来应用它.
你要小心,如果你启动多个进程,每个进程都这样做,你不会最终让一些 CCX 完全闲置。也许每一秒,做任何 top
或 htop
做的事情来检查 per-core 利用率,如果是的话再平衡? (即将两个进程的亲和掩码更改为不同 CCX 的核心)。或者也许将这个功能放在被调度的进程之外,所以有一个“主控制程序”可以查看(并可能修改)它应该控制的一组任务的亲和力掩码。 (并非系统上的所有任务;那将是一种浪费。)
或者如果它正在查看所有内容,则不需要对当前平均负载做太多检查,只需计算在何处安排了什么。 (并假设它不知道的任务可以在任何 CCX 上选择任何空闲核心,例如守护进程或偶尔的编译工作。或者如果所有核心都忙于它管理的工作,至少公平竞争。)
显然这对大多数 parent/child 进程没有帮助,只有那些通过共享内存(或者可能是管道,因为内核管道缓冲区是有效的共享内存)进行大量通信的进程才有用。
的确,Zen CPU 在 CCX 内部/之间具有不同的 inter-core 延迟,以及共享 L3 的缓存命中效果。 https://www.anandtech.com/show/16529/amd-epyc-milan-review/4 对 Zen 3 对比 2 路 Xeon Platinum 对比 2 路 ARM Ampere 进行了一些微基准测试。
现代 AMD CPU 由多个 CCX 组成。每个 CCX 都有一个
可以 set process affinity 将进程限制为某些 CPU 个核心。
有没有办法强制Linux在共享 L3 缓存的两个内核上调度两个进程(父进程线程和子进程),但仍然让调度程序自由选择哪个两个核心?
进程的底层库函数支持设置CPU set masks,它允许您定义一组核心,在这些核心上进程可以运行。有 pthreads 的等价物。参见 this man page and this command line tool。
This 是一篇关于 Linux 如何处理 NUMA 系统的非常有趣的文章。它基本上试图将代码和内存保持在一起,所以它已经 pre-disposed 开箱即用地做你想做的事。虽然我认为如果两个进程之间的交互是通过例如一个分配的共享内存而另一个最终只是“访问”(即在启动第二个进程时,内核不知道它会访问由一个单独的进程分配的内存,它实际上放在一个很远的核心上[用 NUMA 术语])。
我认为 CPU sets 显示了一些希望。在该页面的底部有将 shell 放入特定 CPU 集合的示例。这可能是一种方式,任何从 shell 开始的后续进程都将保留在相同的 CPU 集合中,而您不必为它们专门设置核心亲和力(我认为它们将从shell)。您仍然会根据集合中有哪些 CPU 来定义 CPU 集合,但只定义一次。
如果您手动选择一个 CCX,您可以为它们提供相同的亲和力掩码,使它们可以在该 CCX 中的任何核心上进行调度。
亲和掩码可以设置多个位。
我不知道有什么方法可以让内核决定哪个 CCX,然后将这两个任务安排到其中的内核。如果父级检查它当前 运行 在哪个核心上,它可以设置一个掩码以包括包含它的 CCX 中的所有核心,假设您有一种方法来检测核心 #s 是如何分组的,并且有一个函数来应用它.
你要小心,如果你启动多个进程,每个进程都这样做,你不会最终让一些 CCX 完全闲置。也许每一秒,做任何 top
或 htop
做的事情来检查 per-core 利用率,如果是的话再平衡? (即将两个进程的亲和掩码更改为不同 CCX 的核心)。或者也许将这个功能放在被调度的进程之外,所以有一个“主控制程序”可以查看(并可能修改)它应该控制的一组任务的亲和力掩码。 (并非系统上的所有任务;那将是一种浪费。)
或者如果它正在查看所有内容,则不需要对当前平均负载做太多检查,只需计算在何处安排了什么。 (并假设它不知道的任务可以在任何 CCX 上选择任何空闲核心,例如守护进程或偶尔的编译工作。或者如果所有核心都忙于它管理的工作,至少公平竞争。)
显然这对大多数 parent/child 进程没有帮助,只有那些通过共享内存(或者可能是管道,因为内核管道缓冲区是有效的共享内存)进行大量通信的进程才有用。
的确,Zen CPU 在 CCX 内部/之间具有不同的 inter-core 延迟,以及共享 L3 的缓存命中效果。 https://www.anandtech.com/show/16529/amd-epyc-milan-review/4 对 Zen 3 对比 2 路 Xeon Platinum 对比 2 路 ARM Ampere 进行了一些微基准测试。