我有 6 个核心,想同时并行运行 12 个进程。我正在使用 mpirun,但对于每个核心多进程使用的选项感到困惑。6 个进程的命令就是这样的
mpirun -np 6 ./the program
单核最多可以使用多少个进程
答案1
Linux 内核可以为您启动和管理许多进程;比您合理使用的进程要多。但更重要的问题是:对于您的特定任务,有多少个并行进程是有用的?有多少应该您开始尽可能充分利用您的系统资源吗?
一般情况下,这个问题很难回答。有些任务是 CPU 密集型的,也就是说,它们需要大量的计算能力。有些任务是 I/O 密集型的,也就是说,它们从磁盘读取大量数据或将大量数据写入磁盘。有些任务是网络密集型的,也就是说,它们通过网络传输大量数据。然后是内存使用情况;每个任务都需要一定数量的 RAM,无论是物理 RAM 还是虚拟 RAM,包括交换空间;当交换开始时,一切都会戛然而止,所以您需要避免这种情况。
因此,每个任务都需要几种不同类型的系统资源,即任何并行任务都会竞争的资源:
- 中央处理器
- 内存
- 磁盘 I/O
- 网络 I/O
如果总体任务是运行 10,000 个任务,那么有多少任务适合并行启动取决于它们对系统资源的使用模式。如果每个任务都不太占用大量 CPU,但必须等待网络结果,那么并行运行比 CPU 核心数量多得多的任务可能更有意义。如果它们都从文件中读取大量数据,那么不并行运行那么多任务可能更有效率,因为磁盘 I/O 将成为限制因素。如果它们都读取同一个文件,情况可能相反,因为该文件已经缓存在 I/O 缓冲区中。
这实际上取决于使用模式,并且您通常必须试验特定系统配置的最佳点(取决于 I/O 带宽、CPU 核心数、CPU 使用率、可用 RAM 等)。
答案2
这个答案仅涉及一个核心部分上有多少个线程。
这在很大程度上取决于每个线程的负载和内存。本文中的示例使用最小的内存和每个线程的负载,您可以观察到我获得了每个核心的大量线程。
在此示例中,程序将启动 30 次,每次启动都会产生 1000 个线程。首先,我将查看有多少个进程已与我相关:
~$ cat /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.current
14
然后在后台多次启动该程序:
doug@s18:~/c$ for i in {1..30}; do ./waiter 1000 100 60 2 999999 0 > /dev/null & done
[1] 635246
[2] 635247
[3] 635248
...
[28] 635426
[29] 635434
[30] 635448
再看一下线程数:
doug@s18:~$ cat /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.current
30044
这是 6 核、6 CPU、i5-9600K 处理器。
现在,关于线程的限制,请参阅这个答案,但我也会在这里展示它,但不提供您可以在链接中找到的支持信息。我将以每次 10,000 个线程的速度执行 20 次,总共 200,000 个线程:
doug@s18:~$ cat /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.current
200034
好的,我没有只在一个核心上执行此操作,所以现在这样做:
doug@s18:~/c$ for i in {1..20}; do taskset -c 4 ./waiter 10000 100 60 2 999999 0 > /dev/null & done
[1] 85334
[2] 85335
...
[19] 85353
[20] 85354
没问题,实际上我可以达到大约 254000(如果你一定要知道的话,这是错误的),然后平均负载就会跳到 200000 以上,事情就会真正陷入困境。
top - 13:53:58 up 9 min, 2 users, load average: 100.06, 2488.11, 2014.59
Tasks: 200179 total, 8 running, 200171 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 18.1 us, 25.7 sy, 0.0 ni, 56.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu4 : 25.7 us, 38.7 sy, 0.0 ni, 35.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu5 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 31962.2 total, 6236.9 free, 24814.8 used, 910.5 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 6679.1 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1150 doug 20 0 241796 231484 3132 R 43.0 0.7 2:42.53 top
21 root 20 0 0 0 0 S 0.6 0.0 0:01.94 ksoftirqd/1
1 root 20 0 167628 11468 8356 S 0.0 0.0 0:54.61 systemd
高平均负载是从启动阶段开始的,并且正在快速下降。观察 CPU 4 上仍然有足够的容量,但内存越来越少,但实际上还不错。
但是,systemd 在尝试终止一个核心上的如此多进程时似乎遇到了困难:
top - 14:06:48 up 22 min, 2 users, load average: 143735.08, 78365.08, 32282.72
Tasks: 163872 total, 106906 running, 19503 sleeping, 0 stopped, 37463 zombie
%Cpu0 : 0.2 us, 59.4 sy, 0.0 ni, 40.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 30.5 sy, 0.0 ni, 69.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 12.3 us, 26.4 sy, 0.0 ni, 60.9 id, 0.0 wa, 0.0 hi, 0.4 si, 0.0 st
%Cpu3 : 0.6 us, 4.2 sy, 0.0 ni, 95.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu4 : 0.0 us,100.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu5 : 0.4 us, 1.9 sy, 0.0 ni, 97.5 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 st
MiB Mem : 31962.2 total, 13418.8 free, 17632.6 used, 910.8 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 13861.3 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 167628 11476 8356 S 99.6 0.0 4:08.50 systemd
285365 doug 20 0 241772 231688 3256 R 36.1 0.7 1:28.26 top
如果我坚持足够长的时间,事情就会自行解决。
这里使用的程序是我的,但它是从 1999 年 12 月出版的《Linux 示例编程》一书开始/发展而来的。