如何进行高效的多处理?



>我正在使用多处理。Pool.map 在我的工作站中并行运行我的代码,该工作站有 10 个物理内核(如果我还包括逻辑内核,则为 20 个内核(。

为了总结我的代码,我必须对 2080 个矩阵进行一些计算。因此,我将 2080 个矩阵分成 130 个组,每个组包含 16 个矩阵。

然后,使用多处理将这 16 个矩阵的计算分布在 16 个内核上(既然我只有 10 个物理内核,我应该只使用 10 个吗?(。池地图。

我的问题是:

(1( 当我在 Ubuntu 的"系统监视器"中监控 CPU 的使用情况时,我发现很多时候只有 1 个 CPU 使用率显示 100%,而不是 16 个 CPU 显示 100% 使用率。 16 CPU 仅在短时间内显示 100% 使用率。为什么会这样?如何改进?

(2( 通过将 2080 个矩阵分成 104 组,每组有 20 个矩阵,然后将这 20 个矩阵的计算分布在 10 或 16 个内核上,我是否能够缩短计算时间?

我的代码片段如下:

def f(k):
adj=np.zeros((9045,9045),dtype='bool')
# Calculate the elements of the  matrices
return adj
n_CPU=16
n_networks_window=16
window=int(2080/n_networks_window) #Dividing 2080 matrices into 130 segments having 16 matrices each  
for i in range(window):
range_window=range(int(i*2080/window),int((i+1)*2080/window))
p=Pool(processes=n_CPU)
adj=p.map(f,range_window)
p.close()
p.join()
for k in range_window:
# Some calculations using adj
np.savetxt(') # saving the output as a txt file

任何帮助都将非常有用,因为我是第一次并行化 python 代码。

谢谢。

编辑: 我在代码中尝试了以下中文,现在工作正常: pool.imap_unordered(f,范围(2080(,块大小=260(

你的问题在这里:

for i in range(window):
# [snip]
p=Pool(processes=n_CPU)
adj=p.map(f,range_window)
p.close()
p.join()
# [snip]

您在每个循环中创建一个新池,并且只向其提交几个作业。为了使循环继续,必须先完成少数作业,然后才能执行更多作业。换句话说,您没有充分发挥并行性的潜力。

您应该做的是创建一个池,提交所有作业,然后脱离循环,加入:

p=Pool(processes=n_CPU)
for i in range(window):
# [snip]
p.map_async(f,range_window)
# [snip]
p.close()
p.join()

请注意使用map_async而不是map:同样,这是为了避免在提交新作业之前等待一小部分作业完成。

更好的方法是只调用一次map/map_async,构造单个范围对象并避免 for 循环:

with Pool(processes=n_CPU) as p:
p.map(f, range(2080))  # This will block, but it's okay: we are
# submitting all the jobs at once

至于你关于要使用的CPU数量的问题,首先请注意,Pool将使用所有可用的CPU(如果你不指定processes参数,默认情况下os.cpu_count()返回 - 试一试。

我不清楚你所说的拥有 10 个物理内核和 20 个逻辑内核是什么意思。如果你在谈论超线程,那么没关系:全部使用它们。相反,如果您说您正在使用的虚拟机具有比主机 CPU 更多的虚拟 CPU,那么使用 20 而不是 10 不会有太大区别。

相关内容

  • 没有找到相关文章

最新更新