繁体   English   中英

将子集从大型数据库引导到python中的不同cpu

[英]directing subsets from a large database to different cpus in python

我编写了一些Python代码,它从大型数据库中提取信息,对数据库中的每个项目执行一些最大似然建模,然后存储结果。 代码可以串行工作,每个项目需要1-2秒。 问题是,我在数据库中有几百万个项目,因此代码的连续运行将花费数周时间。 我可以访问一个拥有16个cpus的集群,我编写了一个将初始输入目录分解为“块”的函数,在每个块上运行建模代码,然后组织结果。 由于代码建模部分的复杂性及其对第三方python软件的依赖,我一直在尝试使用多处理来并行化这些代码,以便输入目录的每个块都在一个单独的cpu上运行。 目前,我尝试产生的进程只能在一个cpu上运行。 有谁知道如何解决这一问题? 我是一名自学成才的科学程序员,所以我有一些使用Python的经验,尽管这是我第一次尝试并行化。 代码太长了,无法在此完整显示,但它基本上执行以下操作:

def split(a, n):
    k, m = len(a) / n, len(a) % n
    return (a[i * k + min(i, m):(i + 1) * k + min(i + 1, m)] for i in xrange(n))

ncpus = mp.cpu_count()
chunks = list(split(catlist, ncpus))
images = [im1, im2, im3, im4, im5, im6, im7, im8, im9, im10, im11, im12]

def process_chunks(chunk):
    database_chunk = database[chunk[:]]
    for i in range(0,len(database_chunk)):
        # perform some analysis
        for j in range(0,len(images)):
            # perform more analysis      
    my_dict = {'out1': out1, 'out2':out2, 'out3': out3}
    return my_dict

pool = mp.Pool(processes=ncpus)
result = [pool.apply(process_chunks, args=(chunks[id],)) for id in range(0,len(chunks))]

对于数据库中只有13个项目的简单测试示例,这就是块看起来像(大致均匀分割列表的列表):

chunks = [[0,1,2,3],[4,5,6],[7,8,9],[10,11,12]]

代码运行正常,pool.apply命令产生多个进程,但是所有进程都在一个cpu上运行,并且运行时没有串行改进(事实上它有点慢,我想由于产生每个进程的开销处理)。 有没有办法强制将每个进程分配给一个单独的cpu,所以当我将它应用于完整数据库(有数百万项)时,我得到了一些改进? 或者也许是更好的解决这个问题的方法?

非常感谢你提前!

注意:如果它进一步澄清情况,我是一名天文学家,数据库是一个包含超过一百万条目的大型源目录,图像是12个不同波段的宽场马赛克,我正在进行最大似然测光在每个来源的每个乐队。

我一开始以为你遇到了全局解释器锁,但是你已经通过使用multiprocessing避开它了。 值得庆幸的是,这意味着事情要比其他方面容易得多。 来自文档

相当于apply()内置函数。 它会一直阻塞,直到结果准备就绪 ,因此apply_async()更适合并行执行工作。

(强调我的)

apply_async()apply() API略有不同,但这是一个非常简单的修改:

calculations = []

def reaper(result):
    calculations.append(result)

for id in range(0, len(chunks)):
    pool.apply_async(process_chunks, args=(chunks[id],), callback=reaper)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM