В Python2.7 мне нужно построить 2D-массив (arrayFullCross_final[u][u]
), который содержит 16 блоков с размером каждого блока 100x100 элементов.Вначале я использую массив 4D (arrayFullCross
), затем преобразовываю его в двумерный массив 400x400.
У меня есть первая версия (последовательная), где я использую классическую функцию python «map» и«генератор», подобный этому (buildCrossMatrix_loop
- это функция, к которой я хочу применить генератор generatorCrossMatrix
):
# Build all big matrix with N total blocks = dimBlock*dimBlock = 16 here
arrayFullCross = np.zeros((dimBlocks, dimBlocks, arrayCross_k.size, arrayCross_mu.size))
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 terms
if (xb == yb):
#arrayFullCross[u][u][w][t] = 2*P_bgs**2 * N_bgs**2
if (xb == 0):
N_bgs = (1+1/(n[params_array[2]]*P_obs_cross(arrayCross_k[ub], arrayCross_mu[vb] , z, 10**P_m(np.log10(arrayCross_k[ub])), 10**P_m_NW(np.log10(arrayCross_k[ub])), bias2D_array*sig_8_fid, growth_f[params_array[2]]*sig_8_fid, H_orig(z), H_orig(z), D_A_orig(z), D_A_orig(z), params_array[2], 0, 0)))
arrayFullCross[xb][xb][ub][vb] = 2*P_obs_cross(arrayCross_k[ub], arrayCross_mu[vb] , z, 10**P_m(np.log10(arrayCross_k[ub])), 10**P_m_NW(np.log10(arrayCross_k[ub])), bias2D_array*sig_8_fid, growth_f[params_array[2]]*sig_8_fid, H_orig(z), H_orig(z), D_A_orig(z), D_A_orig(z), params_array[2], 0, 0)**2 * N_bgs**2
...
...
##### MAIN LOOP to fill, at each index i, the array "arrayFullCross" #####
while i < len(zrange):
...
...
def generatorCrossMatrix(index):
for igen in range(dimBlocks):
for lgen in range(dimBlocks):
yield igen, lgen, index
if __name__ == '__main__':
map(buildCrossMatrix_loop, generatorCrossMatrix(i))
...
...
i = i+1
i
- это просто указатель в основной цикл «while».
С помощью этого последовательного метода все работает нормально, и я получаю ожидаемый большой выходной массив arrayFullCross[u][v][x][y]
(я проверил значения в нем и после изменения формы на 400x400, это хорошо).
Теперь япытался делать то же самое, но с multiprocessing import Pool
.Я сделал:
from multiprocessing import Pool
def buildCrossMatrix_loop(params_array):
...
while i < len(zrange):
...
if __name__ == '__main__':
pool = mp.Pool(16)
pool.map(buildCrossMatrix_loop, generatorCrossMatrix(i))
pool.terminate()
# Reshape 4D array to 2D global array
arrayFullCross2D_final = arrayFullCross.swapaxes(1,2).reshape(dimMatCovCross,dimMatCovCross)
print 'arrayFullCross2D_final = ', arrayFullCross2D_final
Но когда я печатаю окончательный выходной массив 2D arrayFullCross2D_final
, я систематически получаю массив, заполненный только нулевыми значениями.
arrayFullCross2D_final = [[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
...
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]]
Возможно, мне нужно сделатьразделял массив 4D arrayFullCross
между разными процессами?Как я могу это сделать?
Как каждый процесс может одновременно изменять разные части массива 4D?
Кажется, что этот глобальный массив 4D перезаписывается для каждого i
индекса цикла.
ОБНОВЛЕНИЕ 1: Я забыл сказать, что я объявил полный массив следующим образом (в начале основного, т.е. вне цикла while
):
# Build all big matrix with N total blocks = dimBlock*dimBlock = 16 here
arrayFullCross = np.zeros((dimBlocks, dimBlocks, arrayCross_k.size, arrayCross_mu.size))
Как я могу использовать решение с данным ответом и моим объявлением arrayFullCross, то есть:
manager = Manager()
arrayFullCross = manager.list()
??
ОБНОВЛЕНИЕ 2: Iхотя я нашел хорошее решение, используя ThreadPool
с from multiprocessing.dummy import Pool as ThreadPool
, таким образом:
pool = ThreadPool(16)
pool.map(buildCrossMatrix_loop, generatorCrossMatrix(i))
pool.close()
pool.join()
Но производительность кажется плохой: действительно, я вижу только один только процесс, запущенный с top
или htop
команд, это нормально?
Кажется, что время в основном тратится на блокировку глобального массива для записи в него: в этом нет необходимости, поскольку я заполняю глобальный массив на независимой подпрограмме.-arrays.
Кто-нибудь уже проверял этот солют?Ион (ThreadPool
)?
Любые другие альтернативы приветствуются, С уважением