python mpi多线程_使用mpi而不是多处理模块时,python中的并行应用变得更慢

最近,当我使用多处理模块和mpi4py作为通信工具测量我的并行应用程序的性能时,我观察到了一个奇怪的影响。

该应用程序对数据集进行演化算法。除了评估之外,大多数操作是按顺序完成的。在所有进化运算符应用之后,所有个体都需要接受新的适应度值,这是在评估过程中完成的。基本上,这只是一个浮动列表(python)的数学计算。在评估之前,数据集由mpi的分散或python的Pool.map分散,然后进行并行评估,然后数据通过mpi的收集或再次的Pool.map机制回来。

我的基准平台是运行Ubuntu 11.10的虚拟机(虚拟机),在Core i7(4/8内核)上有Open MPI 1.4.3,8 GB RAM和SSD驱动器。

我发现真正令人惊讶的是,我获得了一个很好的加速,但是根据通信工具,经过一定的进程阈值后,性能变得更糟。它可以通过下面的图片来说明。

y轴 – 处理时间

x轴 – nr进程

颜色 – 每个人的大小(nr的浮标)

1)使用多处理模块 – Pool.map

2)使用mpi – 散点/收集

3)两张照片彼此顶部

起初我以为这是超线程的错误,因为大型数据集在达到4个进程(4个物理内核)后变慢。但是在多处理的情况下也应该可见,而不是。我的另一个猜测是,mpi通信方法比python的方法要差得多,但是我觉得很难相信。

有没有人对这些结果有任何解释?

添加:

我开始相信这是超线程错误。我在一台带有i5(2/4核心)内核的机器上测试了我的代码,并且3个或更多进程的性能更差。对我来说,唯一的解释是,我使用的i7没有足够的资源(缓存?)与超线程同时计算评估,并且需要安排4个以上的进程在4个物理内核上运行。

然而有趣的是,当我使用mpi htop显示所有8个逻辑内核的完全利用,这应该表明上述语句是不正确的。另一方面,当我使用Pool.Map它并不完全利用所有的核心。它最多只使用一个或两个,而仅部分使用其余的,再次不知道为什么它以这种方式行事。明天我会附上一个屏幕截图,显示这个行为。

我没有在代码中做任何事情,这是非常简单的(我没有给整个代码不是因为它的秘密,而是因为它需要其他的库,如DEAP被安装如果有人真的对这个问题感兴趣,准备好要安装DEAP我可以准备一个简短的例子)。 MPI的代码有点不同,因为它不能处理一个人口容器(从列表继承)。当然有一些开销,但没有什么重大的。除了我下面的代码,其余的是一样的。

Pool.map:

def eval_population(func, pop):

for ind in pop:

ind.fitness.values = func(ind)

return pop

# ...

self.pool = Pool(8)

# ...

for iter_ in xrange(nr_of_generations):

# ...

self.pool.map(evaluate, pop) # evaluate is really an eval_population alias with a certain function assigned to its first argument.

# ...

MPI – 散点/收集

def divide_list(lst, n):

return [lst[i::n] for i in xrange(n)]

def chain_list(lst):

return list(chain.from_iterable(lst))

def evaluate_individuals_in_groups(func, rank, individuals):

comm = MPI.COMM_WORLD

size = MPI.COMM_WORLD.Get_size()

packages = None

if not rank:

packages = divide_list(individuals, size)

ind_for_eval = comm.scatter(packages)

eval_population(func, ind_for_eval)

pop_with_fit = comm.gather(ind_for_eval)

if not rank:

pop_with_fit = chain_list(pop_with_fit)

for index, elem in enumerate(pop_with_fit):

individuals[index] = elem

for iter_ in xrange(nr_of_generations):

# ...

evaluate_individuals_in_groups(self.func, self.rank, pop)

# ...

添加2:

如前所述,我在i5机器上进行了一些测试(2/4内核),结果如下:

我还发现一台机器有2个xeons(2x 6/12内核),并重复了基准:

现在我有3个相同行为的例子。当我在更多的进程中运行我的计算,而不是物理内核,它开始变得更糟。我相信这是因为同一物理核心的进程由于缺乏资源而无法同时执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值