如何将代码与共享可写内存并行化

时间:2017-06-06 11:23:22

标签: python python-multithreading python-multiprocessing

我有一个目前很慢且CPU很重的程序,我对如何将它并行化感到困惑。

我的问题:

算法的工作原理如下(带随机数):

import numpy as np
import scipy.spatial as spatial
from collections import Counter

# Particle dictionary
num_parts = int(1e4)
particles = {'coords': np.random.rand(num_parts, 3),
             'flags': np.random.randint(0, 4, size=num_parts)}

# Object dictionary
num_objects = int(1e3)
objects_dict = {'x': [np.random.rand(1)
                      for i in range(0, num_objects)],
                'y': [np.random.rand(1)
                      for i in range(0, num_objects)],
                'z': [np.random.rand(1)
                      for i in range(0, num_objects)],
                'prop_to_calc': [np.array([])
                                 for i in range(0, num_objects)]}

# Build KDTree for particles
tree = spatial.cKDTree(particles['coords'])

# Loop through objects to calculate 'prop_to_calc' based
# on nearby particles flags within radius, r.
r = 0.1
for i in range(0, num_objects):

    # Find nearby indices of particles.
    indices = tree.query_ball_point([objects_dict['x'][i][0],
                                     objects_dict['y'][i][0],
                                     objects_dict['z'][i][0]],
                                    r)

    # Extract flags of nearby particles.
    flags_array = particles['flags'][indices]

    # Find most common flag and store that in property_to_calculate
    c = Counter(flags_array)
    objects_dict['prop_to_calc'] = np.append(objects_dict['prop_to_calc'],
                                             c.most_common(1)[0][0])

有两个数据集particlesobjects_dict。我想通过搜索半径范围内的附近粒子objects_dict['prop_to_dict']并找到最常见的旗帜来计算r。这是通过cKDTreequery_ball_point完成的。

对于这些数字,时间是: Ipython 4.2.0中的10 loops, best of 3: 55.8 ms per loop

但是,我想要num_parts=1e6num_objects=1e5,这会导致严重的减速。

我的问题:

由于CPU很重,我想尝试将其并行化以加快速度。

我查看了multiprocessingmulti threading。然而,文档让我很困惑,我不知道如何将这些例子应用于这个问题。

具体来说,我关心的是我如何在进程之间共享两个词典并最后写入objects_dict

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

尝试拆分代码并制作本地列表和词典。最后联合词典和列表。只需import threading并使用子类class CalculationThread创建threading.Thread并在类的方法run中编写并行代码,然后按thread = CalculationThread()和{{开始执行该操作1}}

最终的代码是:

thread.start()