单核多进程

单核多进程

我有 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 示例编程》一书开始/发展而来的。

相关内容