Я хотел ускорить свою функцию в классе с именем translate_dirac_delta. Я использовал многопроцессорность для заполнения массива разделяемым массивом в соответствии с этой демонстрацией https://jonasteuwen.github.io/numpy/python/multiprocessing/2017/01/07/multiprocessing-numpy-array.html. Я рассчитал t1-t0 для вызова функции, которая оказалась вдвое быстрее, чем 4 ядра. Однако, когда я использовал функцию времени Unix, она на самом деле в два раза медленнее. Я знаю, что будет несколько подслушано использование многопроцессорных, но я не ожидал, что это будет так много. Модуль, который я использую ssht, является оберткой для Cython, которая не является общедоступной, поэтому не может сделать полный MWE.
Функция синхронизации / вызова
import pyssht as ssht # cython wrapper
def translation(self, flm, pix_i, pix_j):
t0 = time.time()
glm = self.translate_dirac_delta(flm, pix_i, pix_j)
t1 = time.time()
print(t1 - t0)
return glm
def calc_pixel_value(self, ind, pix_i, pix_j):
# create Ylm corresponding to index
ylm_harmonic = np.zeros((self.L * self.L), dtype=complex)
ylm_harmonic[ind] = 1
# convert Ylm from pixel to harmonic space
ylm_pixel = ssht.inverse(ylm_harmonic, self.L, Method=self.method)
# get value at pixel (i, j)
ylm_omega = np.conj(ylm_pixel[pix_i, pix_j])
return ylm_omega
Оригинал
- t1 - t0 = 16,4 с
- реальный 0m16,8
- пользователь 0m22.2s
sys 0m1.5s
def translate_dirac_delta(self, flm, pix_i, pix_j):
flm_trans = self.complex_translation(flm)
return flm_trans
def complex_translation(self, flm):
for ell in range(self.L):
for m in range(-ell, ell + 1):
ind = ssht.elm2ind(ell, m)
conj_pixel_val = self.calc_pixel_value(ind)
flm[ind] = conj_pixel_val
return flm
Параллельное
- t1 - t0 = 8,0 с
- реальный 0m19,5
- пользователь 0m31.9s
sys 0m1.5s
def translate_dirac_delta(self, flm, pix_i, pix_j):
# create arrays to store final and intermediate steps
result_r = np.ctypeslib.as_ctypes(np.zeros(flm.shape))
result_i = np.ctypeslib.as_ctypes(np.zeros(flm.shape))
shared_array_r = multiprocessing.sharedctypes.RawArray(
result_r._type_, result_r)
shared_array_i = multiprocessing.sharedctypes.RawArray(
result_i._type_, result_i)
# ensure function declared before multiprocessing pool
global complex_func
def complex_func(ell):
# store real and imag parts separately
tmp_r = np.ctypeslib.as_array(shared_array_r)
tmp_i = np.ctypeslib.as_array(shared_array_i)
# perform translation
for m in range(-ell, ell + 1):
ind = ssht.elm2ind(ell, m)
conj_pixel_val = self.calc_pixel_value(
ind, pix_i, pix_j)
tmp_r[ind] = conj_pixel_val.real
tmp_i[ind] = conj_pixel_val.imag
# initialise pool and apply function
with multiprocessing.Pool() as p:
p.map(complex_func, range(self.L))
# retrieve real and imag components
result_r = np.ctypeslib.as_array(shared_array_r)
result_i = np.ctypeslib.as_array(shared_array_i)
# combine results
return result_r + 1j * result_i