Многопроцессорность Python, похоже, не использует более одного ядра
Я хочу использовать многопроцессорную обработку Python для запуска поиска сетки для предсказательной модели.
Когда я смотрю на основное использование, всегда кажется, что используется только одно ядро. Любая идея, что я делаю неправильно?
import multiprocessing
from sklearn import svm
import itertools
#first read some data
#X will be my feature Numpy 2D array
#y will be my 1D Numpy array of labels
#define the grid
C = [0.1, 1]
gamma = [0.0]
params = [C, gamma]
grid = list(itertools.product(*params))
GRID_hx = []
def worker(par, grid_list):
#define a sklearn model
clf = svm.SVC(C=g[0], gamma=g[1],probability=True,random_state=SEED)
#run a cross validation fuction: returns error
ll = my_cross_validation_function(X, y, model=clf, n=1, test_size=0.2)
print(par, ll)
grid_list.append((par, ll))
if __name__ == '__main__':
manager = multiprocessing.Manager()
GRID_hx = manager.list()
jobs = []
for g in grid:
p = multiprocessing.Process(target=worker, args=(g,GRID_hx))
jobs.append(p)
p.start()
p.join()
print("\n-------------------")
print("SORTED LIST")
print("-------------------")
L = sorted(GRID_hx, key=itemgetter(1))
for l in L[:5]:
print l
Ответы
Ответ 1
Ваша проблема в том, что вы присоединяетесь к каждой задаче сразу после ее запуска:
for g in grid:
p = multiprocessing.Process(target=worker, args=(g,GRID_hx))
jobs.append(p)
p.start()
p.join()
присоединяйте блоки до тех пор, пока соответствующий процесс не завершит работу. Это означает, что ваш код запускает только один процесс за один раз, ждет, пока он не будет завершен, а затем запустит следующий.
Чтобы все процессы выполнялись параллельно, вам нужно сначала запустить их все, а затем присоединиться к ним все:
jobs = []
for g in grid:
p = multiprocessing.Process(target=worker, args=(g,GRID_hx))
jobs.append(p)
p.start()
for j in jobs:
j.join()
Документация: ссылка
Ответ 2
Я бы сказал:
for g in grid:
g.p = multiprocessing.Process(target=worker, args=(g,GRID_hx))
jobs.append(g.p)
g.p.start()
for g in grid:
g.p.join()
В настоящее время вы создаете задание, а затем продолжаете делать это, а затем переходите к следующему.
Ответ 3
Согласно документации, команда join() блокирует текущий поток до тех пор, пока указанный поток не вернется. Таким образом, вы в основном запускаете каждый поток в цикле for и ждете его завершения, прежде чем переходите к следующей итерации.
Я предлагаю перемещать соединения за пределы цикла!