Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何找到使用python多处理运行的理想并行进程数?_Python_Python 3.x_Parallel Processing_Multiprocessing_Python 3.6 - Fatal编程技术网

如何找到使用python多处理运行的理想并行进程数?

如何找到使用python多处理运行的理想并行进程数?,python,python-3.x,parallel-processing,multiprocessing,python-3.6,Python,Python 3.x,Parallel Processing,Multiprocessing,Python 3.6,试图找出要运行的并行进程的正确数目 下面的脚本运行在一台8核32 GB(Ubuntu 18.04)的机器上。(只有系统进程和基本用户进程在运行,而下面的进程正在测试中。) 测试了多处理池和应用异步,包括以下各项: from multiprocessing import current_process, Pool, cpu_count from datetime import datetime import time num_processes = 1 # vary this print(f"

试图找出要运行的并行进程的正确数目

下面的脚本运行在一台8核32 GB(Ubuntu 18.04)的机器上。(只有系统进程和基本用户进程在运行,而下面的进程正在测试中。)

测试了
多处理池
应用异步
,包括以下各项:

from multiprocessing import current_process, Pool, cpu_count
from datetime import datetime
import time

num_processes = 1 # vary this

print(f"Starting at {datetime.now()}")
start = time.perf_counter()

print(f"# CPUs = {cpu_count()}") # 8
num_procs = 5 * cpu_count() # 40


def cpu_heavy_fn():
    s = time.perf_counter()
    print(f"{datetime.now()}: {current_process().name}")
    x = 1
    for i in range(1, int(1e7)):
        x = x * i
        x = x / i
    t_taken = round(time.perf_counter() - s, 2)
    return t_taken, current_process().name


pool = Pool(processes=num_processes)

multiple_results = [pool.apply_async(cpu_heavy_fn, ()) for i in range(num_procs)]
results = [res.get() for res in multiple_results]
for r in results:
    print(r[0], r[1])

print(f"Done at {datetime.now()}")
print(f"Time taken = {time.perf_counter() - start}s")
结果如下:

num_processes total_time_taken
1 28.25
2 14.28
3 10.2
4 7.35
5 7.89
6 8.03
7 8.41
8 8.72
9 8.75
16 8.7
40 9.53
以下几点对我来说很有意义:

  • 每次运行一个进程大约需要0.7秒,因此运行40个进程大约需要28秒,这与我们上面观察到的一致
  • 一次运行两个进程可以将时间减半,这一点可以在上面观察到(~14秒)
  • 一次运行4个进程可以将时间进一步减半,这一点可以在上面观察到(~7秒)
  • 将并行度增加到超过内核数(8)会降低性能(由于CPU争用),这是可以观察到的(某种程度上)
没有意义的是:

  • 为什么并行运行8的速度不比并行运行4的速度快两倍,即为什么不是~3.5s
  • 为什么一次并行运行5到8比一次运行4更糟糕?共有8个内核,但为什么总体运行时间更差?(当并行运行8时,
    htop
    显示所有CPU的利用率接近100%。当并行运行4时,只有4个CPU的利用率达到100%,这是有道理的。)

最有可能的原因是,您正在使用的CPU上运行程序,通常称为“英特尔”单元。在wiki之后引用,对于物理上存在的每个处理器核心,操作系统寻址两个虚拟(逻辑)核心,并尽可能在它们之间共享工作负载。这就是这里发生的事情


你的操作系统上说是8核,但事实上SMT是4核。该任务显然受到CPU的限制,因此超出物理核数的任何增加都不会带来任何好处,只会带来多处理的开销成本。这就是为什么在达到(物理!)最大内核数(4)之前,性能几乎呈线性增长,然后在需要为这项CPU密集型任务共享内核时,性能下降。

最有可能的原因是,您在使用CPU的CPU上运行该程序,即在英特尔设备上运行该程序。在wiki之后引用,对于物理上存在的每个处理器核心,操作系统寻址两个虚拟(逻辑)核心,并尽可能在它们之间共享工作负载。这就是这里发生的事情

你的操作系统上说是8核,但事实上SMT是4核。该任务显然受到CPU的限制,因此超出物理核数的任何增加都不会带来任何好处,只会带来多处理的开销成本。这就是为什么在达到(物理!)最大内核数(4)之前,性能几乎呈线性增长,然后在需要为这项CPU密集型任务共享内核时,性能下降的原因

Q:“为什么一次并行运行5到8个比一次运行4个更糟糕?”

嗯,
有几个原因,我们将从一个静态的、最容易观察到的原因开始:

由于硅设计(为此他们使用了一些硬件技巧)
的扩展范围不超过4

因此,上一次解释和提升的处理器加速比仅为
+1
递增计数为4,任何下一次+1都不会以{2,3,4}案例中观察到的相同方式递增性能:

lstopo
CPU拓扑图有助于开始解码为什么(此处为4核,但逻辑与您的8核硅相同-在设备上运行
lstopo
,以查看活体内的更多细节):

仔细观察,就像调用
hwloc
-tool:
lstopo no graphics-.ascii
一样,显示了在共享
L1
-指令缓存的级别上,相互处理独立性结束(三级
L3
一级也是共享的,但处于层次结构的顶端,其规模仅对大型问题解决者有影响,而不是我们的案例)


接下来是一个更糟糕的可观察的原因,为什么在8进程上更糟糕: Q:“为什么并行运行8的速度不比并行运行4的速度快两倍,即为什么它不是
~3.5s
?”

由于热管理

CPU内核上的工作量越多,通过硅迷宫驱动电子在
~3.5+GHz
上产生的热量就越多。热约束是那些阻止CPU计算能力进一步提高性能的因素,这仅仅是因为物理定律,正如我们所知道的em,不允许增长超过一些m物质定义的界限

那么接下来是什么?
CPU设计绕过了物理(这是不可能的),而是我们,用户——向我们承诺了一款具有
~3.5+GHz
(但事实上,CPU只能在很短的时间内使用此时钟频率-直到散热使硅接近热极限-然后,CPU将决定降低自己的时钟频率作为过热防御步骤(这会降低性能,不是吗?)或者一些CPU微体系结构可能会跳转到另一个空闲的、因而更冷的CPU内核上(在那里保持较高的时钟速率(至少在一小段时间内),但也会降低性能,因为跳转不会在零时间内发生,也不会以零成本发生(缓存丢失、重新获取等)

这张图片显示了堆芯跳跃情况的快照-堆芯
0-19
变得太热,并且在热节流帽下,
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Machine (31876MB)                                                                                                 │
│                                                                                                                   │
│ ┌────────────────────────────────────────────────────────────┐                      ┌───────────────────────────┐ │
│ │ Package P#0                                                │  ├┤╶─┬─────┼┤╶───────┤ PCI 10ae:1F44             │ │
│ │                                                            │      │               │                           │ │
│ │ ┌────────────────────────────────────────────────────────┐ │      │               │ ┌────────────┐  ┌───────┐ │ │
│ │ │ L3 (8192KB)                                            │ │      │               │ │ renderD128 │  │ card0 │ │ │
│ │ └────────────────────────────────────────────────────────┘ │      │               │ └────────────┘  └───────┘ │ │
│ │                                                            │      │               │                           │ │
│ │ ┌──────────────────────────┐  ┌──────────────────────────┐ │      │               │ ┌────────────┐            │ │
│ │ │ L2 (2048KB)              │  │ L2 (2048KB)              │ │      │               │ │ controlD64 │            │ │
│ │ └──────────────────────────┘  └──────────────────────────┘ │      │               │ └────────────┘            │ │
│ │                                                            │      │               └───────────────────────────┘ │
│ │ ┌──────────────────────────┐  ┌──────────────────────────┐ │      │                                             │
│ │ │ L1i (64KB)               │  │ L1i (64KB)               │ │      │               ┌───────────────┐             │
│ │ └──────────────────────────┘  └──────────────────────────┘ │      ├─────┼┤╶───────┤ PCI 10bc:8268 │             │
│ │                                                            │      │               │               │             │
│ │ ┌────────────┐┌────────────┐  ┌────────────┐┌────────────┐ │      │               │ ┌────────┐    │             │
│ │ │ L1d (16KB) ││ L1d (16KB) │  │ L1d (16KB) ││ L1d (16KB) │ │      │               │ │ enp2s0 │    │             │
│ │ └────────────┘└────────────┘  └────────────┘└────────────┘ │      │               │ └────────┘    │             │
│ │                                                            │      │               └───────────────┘             │
│ │ ┌────────────┐┌────────────┐  ┌────────────┐┌────────────┐ │      │                                             │
│ │ │ Core P#0   ││ Core P#1   │  │ Core P#2   ││ Core P#3   │ │      │     ┌──────────────────┐                    │
│ │ │            ││            │  │            ││            │ │      ├─────┤ PCI 1002:4790    │                    │
│ │ │ ┌────────┐ ││ ┌────────┐ │  │ ┌────────┐ ││ ┌────────┐ │ │      │     │                  │                    │
│ │ │ │ PU P#0 │ ││ │ PU P#1 │ │  │ │ PU P#2 │ ││ │ PU P#3 │ │ │      │     │ ┌─────┐  ┌─────┐ │                    │
│ │ │ └────────┘ ││ └────────┘ │  │ └────────┘ ││ └────────┘ │ │      │     │ │ sr0 │  │ sda │ │                    │
│ │ └────────────┘└────────────┘  └────────────┘└────────────┘ │      │     │ └─────┘  └─────┘ │                    │
│ └────────────────────────────────────────────────────────────┘      │     └──────────────────┘                    │
│                                                                     │                                             │
│                                                                     │     ┌───────────────┐                       │
│                                                                     └─────┤ PCI 1002:479c │                       │
│                                                                           └───────────────┘                       │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘