【问题标题】:Python Multiprocessing - execution time increased, what am I doing wrong?Python Multiprocessing - 执行时间增加,我做错了什么?
【发布时间】:2016-09-29 21:18:12
【问题描述】:

我正在做一个简单的多处理测试,但似乎有些不对劲。我在带有 Turbo Boost 的 i5-6200U 2.3 Ghz 上运行它。

from multiprocessing import Process, Queue
import time

def multiply(a,b,que): #add a argument to function for assigning a queue
    que.put(a*b) #we're putting return value into queue

if __name__ == '__main__':
    queue1 = Queue() #create a queue object
    jobs = []
    start_time = time.time()
#####PARALLEL####################################
    for i in range(0,400):
        p = p = Process(target= multiply, args= (5,i,queue1))
        jobs.append(p)
        p.start()

    for j in jobs:
        j.join()

    print("PARALLEL %s seconds ---" % (time.time() - start_time))
#####SERIAL################################
    start_time = time.time()
    for i in range(0,400):
        multiply(5,i,queue1)
    print("SERIAL %s seconds ---" % (time.time() - start_time))

输出:

PARALLEL 22.12951421737671 seconds ---
SERIAL 0.004009723663330078 seconds ---

非常感谢您的帮助。

【问题讨论】:

  • 创建一个进程比两个小整数相乘要昂贵得多;并且创建比 CPU 多得多的进程会使情况变得更糟(所有进程在有限的 CPU 周期内相互竞争)。要看到任何加速,每个工作进程中完成的“有用工作”需要不平凡(比进程创建+销毁和 IPC(进程间通信)的开销花费更多的时间)。
  • 为什么要创建 400 个进程并将乘法值存储到队列中?
  • 那我应该怎么做呢?你能指出我正确的资源吗?我应该使用游泳池还是什么?我真的很困惑。我需要将值存储到队列中,因为我需要获取过程的结果,并且通过谷歌搜索,队列似乎是这样做的方法
  • 你所做的并没有错。当您为每个进程所做的工作是如此微不足道,以至于开始创建一个进程的成本更高时,根本不可能获得加速。您可以尝试使用 Pool 来代替,使用“只有几个”进程(例如,不超过您拥有的 CPU 数量)。这将大大减少浪费在创建流程上的时间。但是,IPC 仍然比两个小整数相乘更昂贵——你不会得到任何加速。你需要的是一个更昂贵的问题来解决;-)

标签: python multiprocessing python-multiprocessing


【解决方案1】:

这里有一个(愚蠢的)代码的简短示例,它得到了很好的加速。正如 cmets 中已经介绍的那样,它不会创建荒谬的进程数量,并且与进程间通信开销相比,每次远程函数调用完成的工作很高。

import multiprocessing as mp
import time

def factor(n):
    for i in range(n):
        pass
    return n

if __name__ == "__main__":
    ns = range(100000, 110000)

    s = time.time()
    p = mp.Pool(4)
    got = p.map(factor, ns)
    print(time.time() - s)
    assert got == list(ns)

    s = time.time()
    got = [factor(n) for n in ns]
    print(time.time() - s)
    assert got == list(ns)

【讨论】:

  • 谢谢!这很有帮助。但是,我将如何传递 2D 数组(如图像)而不是 n?这是我很困惑的一部分。为了获得价值,我还需要使用队列吗?
  • 盯着代码,你会发现它确实factor()返回结果。我不知道“二维数组(如图像)”到底是什么意思。 “二维数组”和“图像”不是内置的 Python 类型。细节很重要。简而言之,任何可以腌制的东西都可以传递和/或返回
  • 谢谢蒂姆,这对我有很大帮助:)
猜你喜欢
  • 1970-01-01
  • 2016-07-18
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
  • 2016-05-14
  • 2018-04-08
  • 2011-06-01
  • 1970-01-01
相关资源
最近更新 更多