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()