>90%的时间花在'线程.锁'对象的'获取'方法上。

问题描述 投票:7回答:1

为了确定使用了大部分计算时间的步骤,我运行了cProfile,得到了以下结果。

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.014    0.014  216.025  216.025 func_poolasync.py:2(<module>)
    11241  196.589    0.017  196.589    0.017 {method 'acquire' of 'thread.lock' objects}
      982    0.010    0.000  196.532    0.200 threading.py:309(wait)
     1000    0.002    0.000  196.498    0.196 pool.py:565(get)
     1000    0.005    0.000  196.496    0.196 pool.py:557(wait)
515856/3987    0.350    0.000   13.434    0.003 artist.py:230(stale)

花费了大部分时间的步骤显然是: method 'acquire' of 'thread.lock' objects. 我没有使用线程,而是使用了 pool.apply_async 与几个处理器,所以我很困惑为什么 thread.lock 是问题所在?

我希望能得到一些启示,为什么会出现这样的瓶颈?以及如何把这个时间降下来?

下面是代码的样子。

path='/usr/home/work'
filename='filename'

with open(path+filename+'/'+'result.pickle', 'rb') as f:
     pdata = pickle.load(f)

if __name__ == '__main__':
    pool = Pool()    
    results=[]
    data=list(range(1000))
    print('START')
    start_time = int(round(time.time()))
    result_objects = [pool.apply_async(func, args=(nomb,pdata[0],pdata[1],pdata[2])) for nomb in data]

    results = [r.get() for r in result_objects]

    pool.close()
    pool.join()
    print('END', int(round(time.time()))-start_time)

修订:

通过切换 pool.apply_asyncpool.map 我能够减少约3倍的执行时间。

输出。

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.113    0.113   70.824   70.824 func.py:2(<module>)
     4329   28.048    0.006   28.048    0.006 {method 'acquire' of 'thread.lock' objects}
        4    0.000    0.000   28.045    7.011 threading.py:309(wait)
        1    0.000    0.000   28.044   28.044 pool.py:248(map)
        1    0.000    0.000   28.044   28.044 pool.py:565(get)
        1    0.000    0.000   28.044   28.044 pool.py:557(wait)

修改代码。

if __name__ == '__main__':
    pool = Pool()    
    data=list(range(1000))

    print('START')
    start_time = int(round(time.time()))
    funct = partial(func,pdata[0],pdata[1],pdata[2])
    results = pool.map(funct,data)
    print('END', int(round(time.time()))-start_time)

但是,我们发现 一些 的迭代导致了无意义的结果。我不知道为什么会出现这种情况,但是,可以看到'方法'获取'线程.锁'对象'仍然是决定速率的步骤。

python-2.7 multiprocessing profiling cprofile
1个回答
1
投票

剖析器只告诉你主进程在做什么,而它的子进程在做所有的工作。

来源:/stackover https:/stackoverflow.coma225306651064565。

© www.soinside.com 2019 - 2024. All rights reserved.