为啥我的多处理比 youtube 上显示的慢?
Posted
技术标签:
【中文标题】为啥我的多处理比 youtube 上显示的慢?【英文标题】:Why is my multiprocessing slower than that shown on youtube?为什么我的多处理比 youtube 上显示的慢? 【发布时间】:2021-11-03 03:35:24 【问题描述】:import time
import multiprocessing
def do_something():
print("sleep 1 second")
time.sleep(1)
print("Done sleeping...")
if __name__ =='__main__':
start = time.perf_counter()
processes = []
for _ in range(10):
p = multiprocessing.Process(target=do_something)
p.start()
processes.append(p)
for process in processes:
process.join()
finish = time.perf_counter()
print(f'Finished in round(finish-start, 2) second(s)')
上面是我的代码,我想做的是进行多处理,问题是我的代码最终运行了 1.22 秒,而 youtube 上的人只需要 1.02 秒!我正在使用 pycharm (python 3.9) 并检查我的任务管理器,当我运行此代码时,我的 cpu 利用率没有达到最大值,我的内存也是如此。是不是因为我用的是笔记本电脑而不是台式机?我的电脑硬件会影响速度吗? 0.2 秒对我来说意义重大,因为我正在做一个项目,而一秒钟的时间很重要。
或者是因为我使用了if __name__ =='__main__':
,但问题是如果我不使用这一行,我的代码将根本无法运行,但视频中的那个人能够在没有这一行的情况下运行他的代码(我检查了,我没有打开任何其他文件,我只有一个是main.py
,如上所示。我个人认为这不会影响速度,但如果确实如此,请告诉我。
我正在谈论的 youtube 视频是 Corey Schafer 的“Python 多处理教程:使用多处理模块并行运行代码”
视频:Python Multiprocessing Tutorial: Run Code in Parallel Using the Multiprocessing Module
14:09可以看到他运行代码只需要1.02秒
【问题讨论】:
【参考方案1】:if __name__ == "__main__"
是衍生操作系统(如 Windows)所必需的,而不是 fork 系统(如 linux)所必需的。 Windows 运行新进程的速度稍慢一些,因为它需要执行一个新的 python 并从调用进程中提取/分解环境,而 linux 只是分叉并为内存提供不同的视图。我不会感到惊讶,这是你额外的 0.2 秒。请注意,这是一次性的事情,所以如果您的流程有很多工作要做,没什么大不了的。
虽然进程的数量通常很重要,但由于唯一的工作是 sleep(1)
,因此您需要创建许多进程才能做到这一点。
我不知道pycharm是否与它有关。值得在您的命令行上进行测试以查看。
我在我的 linux 笔记本电脑上运行了 1.01 秒。当我像在 Windows 上那样强制“生成”模式时,它上升到 1.11 秒。所以,对我来说,生成的开销是 0.1 秒。
更新
考虑到进程是串行创建的,这就是花费额外时间的地方,我尝试将这部分操作与进程内线程并行化。首先我尝试了一个线程池,但这太慢了,但是仅仅让一个线程创建进程就可以在大约一秒钟内加速代码运行,从而消除了 0.1 秒(在你的情况下是 0.2 秒)的劣势。
import time
import multiprocessing
import threading
def do_something():
print("sleep 1 second")
time.sleep(1)
print("Done sleeping...")
def run_do_something():
p = multiprocessing.Process(target=do_something)
p.start()
processes.append(p)
if __name__ =='__main__':
multiprocessing.set_start_method('spawn')
start = time.perf_counter()
threads = []
processes = []
for _ in range(10):
t = threading.Thread(target=do_something)
t.start()
threads.append(t)
for thread in threads:
thread.join()
for process in processes:
process.join()
finish = time.perf_counter()
print(f'Finished in round(finish-start, 2) second(s)')
【讨论】:
等一下,你甚至没有在你的程序中调用 run_do_something,如果我是对的,你只使用线程而不是多处理?如果我错了,请纠正我【参考方案2】:当然,硬件在运行时间方面很重要,尤其是在使用多道程序时。这取决于内核数量、超线程可能性、CPU 频率和内存。
【讨论】:
虽然您所说的从一般意义上来说可能是正确的,但我认为它不适用于这种情况,因为该任务只是休眠了相对较长的时间——这取消了大部分考虑, @martineau 尽管代码行数较少,但它需要处理能力来调用 pvm、gc 并导入模块和所有预处理内容 我认为这不足以解释差异 - 这可能是因为 OP 使用的是 Windows 而视频中的人不是(以及在操作系统中启动单独进程的方式) .以上是关于为啥我的多处理比 youtube 上显示的慢?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在像 STB 这样的嵌入式系统上,钴在 Youtube 中的性能比铬好得多?
为啥我在 Sklearn 管道中的 OneHotEncoding 后得到的列比预期的多?