【问题标题】:directing subsets from a large database to different cpus in python在python中将子集从大型数据库定向到不同的cpu
【发布时间】:2023-04-02 06:03:01
【问题描述】:

我编写了一些 Python 代码,用于从大型数据库中提取信息,对数据库中的每个项目执行一些最大似然建模,然后存储结果。该代码连续工作正常,每个项目需要 1-2 秒。问题是,我的数据库中有几百万个项目,因此代码的连续运行需要数周时间。我可以访问具有 16 个 cpu 的集群,并且我编写了一个函数,将初始输入目录分解为“块”,在每个块上运行建模代码,然后组织结果。由于代码建模部分的复杂性及其对第 3 方 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 个项目的简单测试示例,这就是块的样子(大致均匀拆分的列表的列表):

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

代码运行良好,pool.apply 命令生成多个进程,但所有进程都在单个 cpu 上运行,并且运行时比串行没有任何改进(实际上它有点慢,我猜是因为开销生成每个进程)。有没有办法强制将每个进程分配给单独的 cpu,以便在将其应用于完整数据库(具有数百万个项目)时得到一些改进?或者也许是解决这个问题的更好方法?

提前非常感谢您!

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

【问题讨论】:

    标签:
    python
    parallel-processing
    multiprocessing