【问题标题】:low efficiency python parallel/multiprocessing with image convolution具有图像卷积的低效率python并行/多处理
【发布时间】:2017-09-07 05:43:40
【问题描述】:

在每个任务中,我有大约 500 张图像作为第一步进行卷积,而且 ndimage.filters 下的过滤器似乎只使用 1 个核心。我用 multiprocessing.queue 尝试了 multiprocessing.pool 和 multiprocessing.process。两者都有效,但运行速度比使用单个进程慢得多。原因很可能是pickle和开销:如果我在每个worker中生成假数据而不是将真实数据传递给每个worker,那么多处理确实会大大提高性能。

我在 Windows 机器上运行 spyder,我会将代码传递给另一台机器上的其他人,因此重新编译 python 和任何低级调整都不适用。

在 matlab 中,卷积透明地利用了多核,并且有 parfor,它可以很好地处理开销。在python中实现多处理卷积有什么想法或建议吗?非常感谢!

【问题讨论】:

  • 尝试自己腌制您的图像数据,看看结果如何。 Pickle 实际上非常有效,不会再查看您的二进制数据。但是请注意,腌制对象所指的对象也会被腌制。我怀疑您实际上是在向您的子流程发送大量内容。

标签: python parallel-processing multiprocessing pickle convolution


【解决方案1】:

如果任务是 numpy/scipy 繁重,那么多处理似乎是一个糟糕的选择。我应该使用多线程而不是多处理,因为大多数 numpy/scipy 函数不受 GIL 影响,由于开销小,多线程优于多处理。

最重要的是,多线程比单线程更快。

import Queue
import threading
import numpy as np
from scipy import ndimage    
import time

repeats = 24

def smooth_img(q,im):
    im_stack_tmp = ndimage.filters.gaussian_laplace(im, 2.)
    q.put(im_stack_tmp)


im_all = [None]*repeats
im_all_filtered = [None]*repeats

for j in range(repeats):
    im_all[j] = np.random.randn(2048,2048)

start = time.time()
for j in range(repeats):
    im_all_filtered[j] = ndimage.filters.gaussian_laplace(im_all[j], 2.)
print('single thread: '+str(time.time()-start))


start = time.time()
q = Queue.Queue()
for im in im_all:
    t = threading.Thread(target=smooth_img, args = (q,im))
    t.daemon = True
    t.start()
for j in range(repeats):
    im_all_filtered[j] = q.get()
print('multi thread: '+str(time.time()-start))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 2016-10-24
    • 1970-01-01
    • 2018-10-19
    • 2011-12-17
    相关资源
    最近更新 更多