我听说过“如果你想从并行应用程序中获得最大性能,你应该创建与你的计算机拥有的 CPU 一样多的进程,并且在每个进程中——创建一些(多少?)线程”。
这是真的吗?
我写了一段代码来实现这个习语:
import multiprocessing, threading
number_of_processes = multiprocessing.cpu_count()
number_of_threads_in_process = 25 # some constant
def one_thread():
# very heavyweight function with lots of CPU/IO/network usage
do_main_work()
def one_process():
for _ in range(number_of_threads_in_process):
t = threading.Thread(target=one_thread, args=())
t.start()
for _ in range(number_of_processes):
p = multiprocessing.Process(target=one_process, args=())
p.start()
是否正确?我的 do_main_work
函数真的可以并行运行,不会面临任何 GIL 问题吗?
谢谢。
最佳答案
这在很大程度上取决于你在做什么。
请记住,在 CPython 中,一次只有 一个 线程可以执行 Python 字节码(因为 GIL)。因此,对于 CPython 线程中的计算密集型问题,不会有太大帮助。
分散可以并行完成的工作的一种方法是使用multiprocessing.Pool
。默认情况下,这不会使用您的 CPU 拥有的内核更多的进程。使用更多的进程主要是为了争夺资源(CPU、内存),而不是完成有用的工作。
但是利用多个处理器需要您为它们做一些工作!换句话说,如果问题不能分解成更小的部分,可以单独并行计算,那么许多 CPU 内核将没有多大用处。
此外,并非所有问题都受必须完成的计算量的限制。
计算机的 RAM 比 CPU 慢得多。如果您正在处理的数据集比 CPU 的缓存大得多,那么从 RAM 读取数据并将结果返回到 RAM 可能会成为速度限制。这叫做 memory bound .
而且,如果您处理的数据比机器内存所能容纳的多得多,您的程序就会从磁盘进行大量读写操作。磁盘与 RAM 相比很慢,与 CPU 相比非常慢,因此您的程序变为 I/O-bound .
关于python - Python 中具有多个线程的多个进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25037154/