SO community,
Я борюсь с многоядерным программированием на Python.Хотя я не могу раскрыть слишком много подробностей о цели своего кода, из-за политики информационной безопасности компании я постараюсь быть максимально конкретным.
Я разрабатываю код, который будет оценивать еженедельнобаллы для нескольких человек, разделенные на 5 групп в соответствии с их общими баллами.У меня есть довольно большой фрейм данных, состоящий из десятков тысяч строк, каждая с идентификатором игрока, рассматриваемой неделей (в течение девяти недель) и его / ее счетом на данной неделе.Кроме того, у меня есть пять массивов индексов, поэтому я могу найти / iloc данные для выбора людей в одной из пяти групп, в зависимости от их оценок.
Я написал сериализованную версию этого кода, но этоНа обработку небольшой части (около 150 тыс. строк) наших данных уходит более часа (я разрабатываю небольшой образец, поэтому я могу протестировать код и, как только все будет в порядке, я могу запустить его с помощьюполный набор данных).Структура сериализованного кода в питоническом псевдокоде:
def weekscore(week, ID, players):
mask(week)
players.loc[players['player'==ID]
score = (calculate score)
return score
И затем для всех игроков и всех недель:
sc_week = []
for play_ID in playerlist:
for week in np.arange(0,10): # To consider 9 weeks
sc_week.append(weekscore(week, play_ID, players)
, т. Е. Для каждого игрока в списке, получает его /ее оценка за данную неделю и добавление в список из 9 элементов для дальнейшей обработки.
Я знаю, что это не лучший способ решения этой проблемы, но, поскольку я пытался реализовать многоядерный алгоритм,Я не удосужился оптимизировать этот.В конце концов, это казалось идеальной возможностью выучить важный навык, который будет полезен позже.
В любом случае, я пытался всеми возможными способами в SO реализовать алгоритм многопроцессорной обработки для этой проблемы.Идея состоит в том, чтобы делегировать разные player_ID для разных процессов, чтобы я мог значительно сократить общее время обработки.У меня есть доступ к 32-ядерным компьютерам, поэтому, если бы я мог запустить их с 20 ядрами, я бы ожидал, что код будет работать как минимум в 10 раз быстрее, как минимум.
Но независимо от того, что я реализовал, даже есликод разбивает процесс на несколько процессов, он все еще обрабатывает один player_ID за раз.Я контролировал выполнение через htop в Linux и через диспетчер задач в Windows и в обеих системах, установив размер пула 8, 8 подпроцессов были созданы.Затем один из них будет иметь скачок до 100% ЦП, выводит что-то на экран, затем другой - до 100%, выводится на экран, другой - до 100%, выводится и так далее.Я ожидал, что все процессы достигнут 100%, но я не смог этого сделать.
Самое близкое, что я получил, было с этим:
if __name__ == '__main__':
users, primeiro, dados, index_pred_80, intervalos, percents_ = prepara()
print('Multiprocessing step')
import multiprocessing as mp
from multiprocessing import freeze_support
from functools import partial
freeze_support()
pool = mp.Pool(10)
constparams = partial(perc1, week = week, ID = ID, players = players)
pool.map(constparams, users)
pool.close()
pool.join()
Вызов функции perc1, которая является (анонимно по соображениям конфиденциальности)
def perc1(week, ID, players):
list1 = []
for week in np.arange(0,10):
mask(week)
players.loc[players['player'==ID]
print('Week = ', week, 'Player ID = ', player_ID)
score = (calculate score)
list1.append(score)
return (lista1)
Итак, после длинного поста, как лучше всего достичь этой цели?Каков наилучший способ делегирования пакетов идентификаторов для разных процессов, чтобы каждый процесс мог обрабатывать часть данных?
РЕДАКТИРОВАТЬ 1: исправлены мелкие опечатки.
РЕДАКТИРОВАТЬ 2: я в курсеиз-за ограничений интерактивных интерпретаторов для многоядерного Python, поэтому я протестировал код в командной строке как в Windows, так и в Linux, но поведение было одинаковым в обоих случаях.