猿问

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

在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 block

arrayCross_k = np.linspace(kMIN, kMAX, dimPoints)

arrayCross_mu = np.linspace(-1, 1, dimPoints)

# Build all big matrix with N total blocks = dimBlock*dimBlock = 16 here

arrayFullCross = np.zeros((dimBlocks, dimBlocks, arrayCross_k.size, arrayCross_mu.size))

dimBlocks = 4

# Size of dimension along k and mu axis

dimPoints = 100

# dimension along one dimension of global arrayFullCross

dimMatCovCross = 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上面的主循环中:


UYOU
浏览 172回答 1
1回答

翻过高山走不出你

首先,我认为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被卡住。你可能想看看这个类似的问题,这我回答了两三分钟前。
随时随地看视频慕课网APP

相关分类

Python
我要回答