Параллельная обработка питонов - PullRequest
0 голосов
/ 21 сентября 2018

Я в следующей настройке: у меня есть метод, который принимает целевую функцию f в качестве ввода.Подразделением этого метода я хочу оценить f по небольшому набору точек.Поскольку f имеет высокую сложность, я подумал сделать это параллельно.Все онлайн-примеры зависают даже для таких тривиальных функций, как возведение в квадрат на сетах с 5 баллами.Они используют многопроцессорную библиотеку - и я не знаю, что я делаю неправильно.Я не уверен, как инкапсулировать это __name__ == "__main__" утверждение в моем методе.(поскольку он является частью модуля - я думаю, что вместо "__main__" мне следует использовать имя модуля?)

Код, который я использовал, выглядит как

from multiprocessing.pool import Pool
from multiprocessing import cpu_count

x = [1,2,3,4,5]
num_cores = cpu_count()
def f(x):
    return x**2

if __name__ == "__main__":
    pool = Pool(num_cores)
    y = list(pool.map(f, x))
    pool.join()
    print(y)

При выполнении этого кодав моем spyder это занимает чертовски много времени, чтобы закончить.

Итак, мои главные вопросы: Что я делаю не так в этом коде?Как я могу инкапсулировать оператор __name __-, если этот код является частью более крупного метода?Стоит ли даже распараллеливать это?(оценка одной функции может занять несколько минут, а в последовательном режиме это составляет общее время работы часов ...)

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Согласно документации :

close ()

Prevents any more tasks from being submitted to the pool. Once all the tasks have been completed the worker processes will exit.

terminate ()

Stops the worker processes immediately without completing outstanding work. When the pool object is garbage collected

terminate () будетбыть вызванным немедленно.

join ()

Wait for the worker processes to exit. One must call close() or terminate() before using join().

Поэтому вы должны добавить:

from multiprocessing.pool import Pool
from multiprocessing import cpu_count

x = [1,2,3,4,5]

def f(x):
    return x**2

if __name__ == "__main__":
    pool = Pool()
    y = list(pool.map(f, x))
    pool.close()
    pool.join()
    print(y)

Вы можете вызывать Pool без каких-либо аргументов, и он будет использоватьcpu_count по умолчанию

Если процессы равны None, то используется число, возвращаемое cpu_count ()

Об операторе if name == " main", читайте больше информации здесь .

Поэтому вам нужно немного подумать о том, какой код вы хотите выполнить только в основной программе.Наиболее очевидный пример - это то, что вы хотите, чтобы код, который создает дочерние процессы, выполнялся только в основной программе - так что он должен быть защищен name == ' main '

0 голосов
/ 21 сентября 2018

Возможно, вы захотите взглянуть на аргумент chunksize используемой вами функции карты.

В достаточно большом входном списке вы тратите много времени, просто передавая аргументы отдельным параллельным процессам и от них.

Одним из симптомов этой проблемы является то, что при использовании чего-то вроде htop все ядра работают, но при <100%. </p>

...