为了账号安全,请及时绑定邮箱和手机立即绑定

将独立块填充到全局数组中的“进程”或“线程”策略?

将独立块填充到全局数组中的“进程”或“线程”策略?

UYOU 2021-11-09 15:05:15
在python2中,我想通过填充并行进程(或线程)不同的子数组(总共有16个块)来填充全局数组。我必须明确每个块不依赖于其他块,我的意思是当我执行当前块的每个单元格的分配时。1)根据我的发现,通过使用不同的“ processes” ,我将从 CPU 多核中受益匪浅,但让所有其他进程共享全局数组似乎有点复杂。2)从另一个角度来看,我可以使用“ threads”代替“ processes”,因为实现起来不那么难。我发现 libray " ThreadPool" from " multiprocessing.dummy" 允许所有其他并发线程共享这个全局数组。例如,使用 python2.7,以下代码有效:from multiprocessing.dummy import Pool as ThreadPool## discretization along x-axis and y-axis for each blockarrayCross_k = np.linspace(kMIN, kMAX, dimPoints)arrayCross_mu = np.linspace(-1, 1, dimPoints)# Build all big matrix with N total blocks = dimBlock*dimBlock = 16 herearrayFullCross = np.zeros((dimBlocks, dimBlocks, arrayCross_k.size, arrayCross_mu.size))dimBlocks = 4# Size of dimension along k and mu axisdimPoints = 100# dimension along one dimension of global arrayFullCrossdimMatCovCross = dimBlocks*dimPoints# Build cross-correlation matrix def buildCrossMatrix_loop(params_array):  # rows indices  xb = params_array[0]  # columns indices  yb = params_array[1]  # Current redshift  z = zrange[params_array[2]]  # Loop inside block  for ub in range(dimPoints):    for vb in range(dimPoints):      # Diagonal blocs       if (xb == yb):      # Fill the (xb,yb) su-block of global array by         arrayFullCross[xb][xb][ub][vb] = 2*P_obs_cross(arrayCross_k[ub], arrayCross_mu[vb] , z, 10**P_m(np.log10(arrayCross_k[ub])),但不幸的是,即使使用 20 个线程,我也意识到我的 CPU 的核心没有完全运行(实际上,使用 'top' 或 'htop' 命令,我只能看到 100% 的单个进程)。3)如果我想充分利用我的 CPU 的 16 个内核,我必须选择什么策略(就像pool.map(function, generator)) but with also the sharing of global array?4)有些人告诉我为每个子数组做I/O(基本上,将每个块写入文件并通过读取它们收集所有子数组并填充完整数组)。这个解决方案很方便,但我想避免 I/O(除非真的没有其他解决方案)。5)我已经练习MPI library了C language填充子阵列的操作,最后将它们聚集起来构建一个大阵列,不是很复杂。但是,我不想MPI与 Python 语言一起使用(即使它存在我也不知道)。6)我还尝试将Process目标等于我的填充函数(buildCrossMatrix_loop)这样使用到while上面的主循环中:
查看完整描述

1 回答

?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

首先,我认为multiprocessing.ThreadPool是私有 API,因此您应该避免使用它。现在multiprocessing.dummy是一个无用的模块。它并没有做任何多线程/处理这就是为什么你看不到任何好处。您应该使用“普通”multiprocessing模块。

第二个代码不起作用,因为它使用了多个进程。进程不共享内存,因此您在子进程中所做的更改不会反映在其他子进程或主进程中。你要么想:

  • 返回值并在主进程中将它们组合在一起,例如使用 multiprocessing.Pool.map

  • 使用threading而不是multiprocessing: just replaceimport multiprocessing withimport threading andmultiprocessing.Process withthreading.Thread` 并且代码应该可以工作。

请注意,该threading版本将工作只是因为numpy发布的计算过程中GIL,否则将在1个CPU被卡住。

你可能想看看这个类似的问题,我回答了两三分钟前。


查看完整回答
反对 回复 2021-11-09
  • 1 回答
  • 0 关注
  • 170 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号