如果我使用多个进程,为什么Python代码运行得更慢

时间:2017-11-17 10:09:22

标签: python performance python-multiprocessing pool

您好,因为未能加快我的代码,我此刻非常沮丧: 我尝试了不同的东西,现在我使用了多处理器池。为了评估Processornumbers的加速和效果,我改变了我使用的处理器数量。但是,如果增加处理器数量,我会失去速度。我不知道为什么,因为理论上我计算8个图像并行,如果我有8个进程,4个如果我使用4个进程。当然有一个开销,但这不应该是一个很大的瓶颈。有没有人发现这里的错误?亲切的问候Max

'''
Created on 17.11.2017

@author: Max
'''
#!/usr/bin/env python

import os, sys, errno
import re
import argparse
from time import time
import multiprocessing
import glob
import numpy as np
import matplotlib.pyplot as plt
import cv2
def computeFeatures(input, chunk_num):
    thresholded_chunk = []
    #print("Processing Chunk,",chunk_num)
    cv2.threshold(input,127,255,cv2.THRESH_BINARY_INV)
    cv2.threshold(input,127,255,cv2.THRESH_BINARY_INV)
    cv2.threshold(input,127,255,cv2.THRESH_BINARY_INV)
    cv2.threshold(input,127,255,cv2.THRESH_BINARY_INV)
    thresholded_chunk.append(cv2.threshold(input,127,255,cv2.THRESH_BINARY_INV))   
    return (thresholded_chunk, chunk_num)


if __name__ == '__main__':
    num_Proc = 2
    max_Proc = 20
    while num_Proc != max_Proc:

        start = time()
        # Handle command line options
        numProcessors = num_Proc

        # Start my pool
        pool = multiprocessing.Pool(numProcessors)

        # Build task list
        path = "InputSimulation\*" 
        tasks = []
        image_list= []
        img_idx = 0
        image_pathes = glob.glob(path+".jpg")
        results = []
        index_for_chunk = numProcessors
        while img_idx < len(image_pathes):
            #print("InsterImageNumber",img_idx)
            tasks.append( (cv2.imread(image_pathes[img_idx],0), img_idx, ) )
            if img_idx % numProcessors == 0:
                result = [pool.apply_async( computeFeatures, t ) for t in tasks]
                results.append(result)
                tasks = []
            img_idx +=1
        pool.close()
        pool.join()
            # Run tasks    #Flatten list before print

        end = time()
        print("DURATION FOR " +str(num_Proc) +" PROCESSES",end - start)
        num_Proc +=1
        # Process results

1 个答案:

答案 0 :(得分:0)

由于您没有使用apply_async的任何回调函数并且始终使用相同的函数(computeFeatures),因此最好使用Pool.map()。在您当前的用例中,apply_async不会并行执行任何计算。最重要的是,它会增加每次计算的开销。

示例:

from multiprocessing import Pool
from math import sqrt

p = Pool(8)
num_list = range(100000)

%%time
_ = p.map(sqrt, num_list)
  

CPU时间:用户19毫秒,系统:2.36毫秒,总计:21.4毫秒

     

壁垒时间:27.7毫秒

%%time
_ = [sqrt(num) for num in num_list]
  

CPU时间:用户33.7 ms,sys:5.93 ms,总计:39.6 ms

     

壁垒时间:37.5毫秒

%%time
_ = [p.apply_async(sqrt, num) for num in num_list]
  

CPU时间:用户5.5秒,系统:1.37秒,总计:6.87秒

     

壁垒时间:5.95秒

如此示例所示。最简单的计算最好使用Pool.map()将代码更改为使用map,您可能会看到一些改进。同样重要的是找到适合您系统的正确工人数量和手头的问题。

result = pool.map(computeFeatures, tasks)