Я пишу универсальный c алгоритм оптимизации на основе пакета deap в python 2.7 (цель - в ближайшее время перейти на python 3). Поскольку это довольно сложный процесс, некоторые части оптимизации обрабатываются с помощью многопроцессорного пакета. Вот краткое описание моей программы:
- Конфигурации считываются и сохраняются в
config
объекте - Некоторые дополнительные предварительные вычисления выполняются и сохраняются также в
config
объект - Оптимизация начинается (популяция инициализируется случайным образом и происходят мутации, для нахождения лучшего решения применяется кроссовер), а некоторые ее части (функция оценки) выполняются в многопроцессорной среде
- Результаты сохранены
Для функции оценки нам нужен доступ к некоторым частям объекта config
(который после фазы 2 остается постоянным). Поэтому мы делаем его доступным для разных ядер, используя глобальную (постоянную) переменную:
from deap import base
import multiprocessing
toolbox = base.Toolbox()
def evaluate(ind):
# compute evaluation using config object
return(obj1,obj2)
toolbox.register('evaluate',evaluate)
def init_pool_global_vars(self, _config):
global config
config = _config
...
# setting up multiprocessing
pool = multiprocessing.Pool(processes=72, initializer=self.init_pool_global_vars,
initargs=[config])
toolbox.register('map', pool.map_async)
...
while tic < max_time:
# creating new individuals
# computing in optimisation the objective function on the different individuals
jobs = toolbox.map(toolbox.evaluate, ind)
fits = jobs.get()
# keeping best individuals
Мы в основном делаем разные итерации (большие для l oop), пока не будет достигнуто максимальное время. Я заметил, что если я сделаю объект конфигурации больше (то есть добавлю к нему большие атрибуты, например, большой массив numpy), даже если код все тот же, он будет работать намного медленнее (меньше итераций за тот же промежуток времени). Поэтому я подумал, что создам указанный объект c config_multiprocessing
, который содержит только атрибуты, необходимые в многопроцессорной части, и передам его как глобальную переменную, но когда я запускаю его на 3 ядрах, он медленнее, чем с большим config
объект и на 72 ядрах, это немного быстрее, но не намного.
Что я должен сделать, чтобы убедиться, что мои циклы не страдают по скорости от объекта конфигурации или от любых других манипуляций с данными, которые я сделать перед запуском многопроцессорных циклов?
Запуск в образе Linux docker на виртуальной машине linux в облаке.