[英]Python: How to multiprocess my function with multiple arguments?
我的 function sound_proc.windowing()
从一个目录中切割一些声音文件并将这些块保存到另一个目录。 要剪切目录中的所有文件,我使用 for 循环遍历所有文件:
# emodb_path_src = source folder with all sound files in it
# 512 = fix integer
# emodb_path_train = destination folder where all the cut files go
files = [l for l in listdir(emodb_path_src)]
for index, file in enumerate(files):
print(f'File: {index+1}/{len(files)}')
sound_proc.windowing(f'{emodb_path_src}{file}', 512, emodb_path_train)
不幸的是,这个过程非常缓慢,因为只使用了一个处理器内核。 我已经尝试过使用multiprocessing
和Pool
,但我无法让它工作。 如果有人能给我一些提示让它在多个内核上运行,那就太好了。
提前感谢您,祝您有美好的一天!
是的,您可以将多处理池与星图结合使用。 诀窍是创建一个可迭代的可迭代对象,其中包含所有 function 调用的所有参数,如下所示:
import multiprocessing as mp
# Precreate the args
args = [(f'{emodb_path_src}{file}', 512, emodb_path_train) for file in listdir(emodb_path_src)]
with mp.Pool(mp.cpu_count()) as pool:
print(pool.starmap(sound_proc.windowing, args))
根据 I/O 绑定问题的方式,您可能还想尝试ThreadPool
。 它使用起来更简单,在某些情况下甚至比Pool
更快,因为它的设置开销更少。 另一个额外的优势是它们共享相同的 GIL,因此您可以访问相同的变量空间。 这是一个片段,注意区别只是一个新的导入和 with 语句:
import multiprocessing as mp
from multiprocessing.pool import ThreadPool # thread-based Pool
# Precreate the args
args = [(f'{emodb_path_src}{file}', 512, emodb_path_train) for file in listdir(emodb_path_src)]
# If it's very I/O bound it might even be worthwhile creating more threads than CPU count!
with ThreadPool(mp.cpu_count()) as pool:
print(pool.starmap(sound_proc.windowing, args))
与此同时,我找到了一个很好的解决方案。 代码 von Gerard 的作用也很迷人。 我想简要地向您展示我现在是如何解决它的,以及使用不同的方法可以节省多少时间。
原始帖子中的普通for循环:
计算持续时间: ~ 457.7 秒
files = [l for l in listdir(emodb_path_src)]
for index, file in enumerate(files):
print(f'File: {index+1}/{len(files)}')
sound_proc.windowing(f'{emodb_path_src}{file}', 512, emodb_path_train)
Gerard提供的解决方案:
计算持续时间: ~ 75.2 秒
import multiprocessing as mp
args = [(f'{emodb_path_src}{file}', 512, emodb_path_train) for file in listdir(emodb_path_src)]
with mp.Pool(mp.cpu_count()) as pool:
pool.starmap(sound_proc.windowing, args)
使用 joblib.Parallel:
计算持续时间: ~ 68.8 秒
from joblib import Parallel, delayed
import multiprocessing as mp
Parallel(n_jobs=mp.cpu_count(), backend='multiprocessing')(delayed(sound_proc.windowing)
(
sound_file=f'{emodb_path_src}{file}',
window_size=512,
dest=emodb_path_train
) for file in files)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.