Я вычисляю сложный, и некоторые процедуры этой функции медленные. Поэтому я использовал Фортран и многопроцессорность вместе, чтобы ускорить свой код.
Например, эта функция (без многопроцессорности) выглядит так:
from fortran_module import fortran_func1, fortran_func2
def test():
# some codes... [A]
res1 = fortran_func1(...)
# some codes... [B]
res2 = fortran_func2(res1, ...)
return res2
fortran_module
скомпилирован из f2py
.
И если я использовал line_profiler
для анализа этого кода, он сказал мне, что коды части [A]
стоят 100 мс, fortran_func1
стоят 300000 мс, [B]
стоят 1000 мс и fortran_func2
стоимость 100000мс.
Я хочу ускорить fortran_func1
, поэтому переписал (исходная версия рассчитывается в 3-х мерном пространстве, а новая версия рассчитывается только в 2-х мерном пространстве), и вместе с многопроцессорностью:
from multiprocessing import Pool
from fortran_module import fortran_func1_new, fortran_func2
def fortran_func1_new_wrapper(...):
"""in order to make it picklable, so can be used in multiprocessing"""
return fortran_func1_new(...)
def func1_pool(...):
args = ... # create a list of `fortran_func1_wrapper` arguments
pool = Pool()
res_list = pool.starmap(fortran_func1_new_wrapper, args)
return np.stack(res_list, axis=-1)
def test():
# some codes... [A] # -- speed of this part doesn't change
res1 = func1_pool(...) # -- speed of this is FASTER comparing to the old version
# some codes... [B] # -- speed of this part is SLOWER than the old version
res2 = fortran_func2(res1, ...) # -- speed of this is SLOWER than the old version
return res2
Результат идентичен предыдущему. Но line_profiler
сказал мне кое-что странное. В этой новой версии коды части [A]
стоят почти 100 мс, func1_pool
стоят 200000 мс, [B]
стоят 2000 мс, а fortran_func2
стоят 200000 мс.
Другими словами, хотя скорость func1_pool
выше, чем в старой версии, ВСЕ коды ПОСЛЕ func_pool
на МЕДЛЕННО , чем в старой версии. И все коды после func1_pool
точно такие же, как и в старой версии.
Я не знаком с multiprocessing
. Кто-нибудь знает, что случилось? Ожидается, что func1_pool
быстрее, чем в старой версии, но почему коды после func1_pool
медленнее? И как мне избежать этой проблемы?
Большое спасибо!