Пожалуйста, не используйте кавычки для акцента. Они предназначены для разметки цитат, а не для подсвечивания произвольных блоков текста или привлечения внимания к вашим заголовкам. Мы уже обсуждали это раньше, есть объективно правильные и неправильные способы использования некоторых инструментов форматирования, которые предоставляет этот сайт, таких как кавычки. Как правило, вы можете свободно форматировать свои сообщения по своему усмотрению, но если кто-то исправит проблему, когда вы неправильно пометили свое сообщение, вы должны оставить свои правки в покое.
аюсь реализовать многопроцессорность в Python (Windows Server 2012) и испытываю трудности с достижением ожидаемого уровня повышения производительности. В частности, для ряда задач, которые почти полностью независимы,Я ожидаю линейного улучшения с дополнительными ядрами.
Я понимаю, что - особенно в Windows - есть издержки, связанные с открытием новых процессов[1]и что многие причуды базового кода могут помешать чистой тенденции. Но в теории тенденция в конечном итоге должна быть близкой к линейной для полностью распараллеленной задачи[2]; или, возможно, логистика, если я имел дело с частично последовательной задачей[3].
Однако, когда я запускаю multiprocessing.Pool для тестовой функции простой проверки (код ниже), я получаю почти идеальное отношение квадратного корня доN_cores=36
(количество физических ядер на моем сервере), прежде чем ожидаемая производительность достигнет, когда я войду в дополнительные логические ядра.
Вот график результатов моего теста производительности:
("Нормализованная производительность" является[ время выполнения с1 CPU-ядра] деленное на[ время выполнения сN CPU-ядра] ).
Нормально ли это резкое уменьшение отдачи при многопроцессорной обработке? Или я что-то упустил в своей реализации?
import numpy as np
from multiprocessing import Pool, cpu_count, Manager
import math as m
from functools import partial
from time import time
def check_prime(num):
#Assert positive integer value
if num!=m.floor(num) or num<1:
print("Input must be a positive integer")
return None
#Check divisibility for all possible factors
prime = True
for i in range(2,num):
if num%i==0: prime=False
return prime
def cp_worker(num, L):
prime = check_prime(num)
L.append((num, prime))
def mp_primes(omag, mp=cpu_count()):
with Manager() as manager:
np.random.seed(0)
numlist = np.random.randint(10**omag, 10**(omag+1), 100)
L = manager.list()
cp_worker_ptl = partial(cp_worker, L=L)
try:
pool = Pool(processes=mp)
list(pool.imap(cp_worker_ptl, numlist))
except Exception as e:
print(e)
finally:
pool.close() # no more tasks
pool.join()
return L
if __name__ == '__main__':
rt = []
for i in range(cpu_count()):
t0 = time()
mp_result = mp_primes(6, mp=i+1)
t1 = time()
rt.append(t1-t0)
print("Using %i core(s), run time is %.2fs" % (i+1, rt[-1]))
Примечание: Я знаю, что для этой задачи было бы более эффективно реализоватьнарезания резьбы, но фактический скрипт, для которого этот является упрощенным аналогом, несовместим с многопоточностью Python из-за GIL.