Multiprocessing.dummy в Python не использует 100% CPU
Я делаю проект машинного обучения на Python, поэтому мне нужно сделать функцию параллельного предсказания, которую я использую в своей программе.
from multiprocessing.dummy import Pool
from multiprocessing import cpu_count
def multi_predict(X, predict, *args, **kwargs):
pool = Pool(cpu_count())
results = pool.map(predict, X)
pool.close()
pool.join()
return results
Проблема в том, что все мои процессоры загружены только на 20-40% (в сумме это 100%). Я использую multiprocessing.dummy, потому что у меня есть некоторые проблемы с многопроцессорным модулем в функции травления.
Ответы
Ответ 1
Когда вы используете multiprocessing.dummy
, вы используете потоки, а не процессы:
multiprocessing.dummy
реплицирует API multiprocessing
, но не является больше, чем обертка вокруг модуля threading
.
Это означает, что вы ограничены Global Interpreter Lock (GIL), и только один поток может фактически выполнять операции с привязкой к процессору за раз. Это поможет вам полностью использовать ваши процессоры. Если вы хотите получить полный parallelism по всем доступным ядрам, вам нужно будет решить проблему травления с помощью multiprocessing.Pool
.
Обратите внимание, что multiprocessing.dummy
может по-прежнему быть полезным, если работа, которую нужно распараллелить, связана с IO или использует C-расширение, которое выпускает GIL. Однако для чистого кода Python вам понадобится multiprocessing
.
Ответ 2
Простой пример многопроцессорности, способ начать и сделать это простым.
import urllib2
from multiprocessing.dummy import Pool as ThreadPool
urls = [
'http://www.python.org',
'http://www.python.org/about/',
'http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html',
'http://www.python.org/doc/',
'http://www.python.org/download/',
'http://www.python.org/getit/',
'http://www.python.org/community/',
]
# Make the Pool of workers
pool = ThreadPool(4)
# Open the urls in their own threads
# and return the results
results = pool.map(urllib2.urlopen, urls)
#close the pool and wait for the work to finish
pool.close()
pool.join()