#python #python-3.x #multithreading #multiprocessing #python-3.7
Вопрос:
Поэтому я создал программу, которая вычисляет простые числа, чтобы проверить, в чем разница между использованием многопоточности или просто использованием одного потока. Я читал, что многопроцессорная обработка обходит GIL, поэтому я ожидал приличного повышения производительности.
Итак, здесь у нас есть мой код для его тестирования:
def prime(n):
if n == 2:
return n
if n amp; 1 == 0:
return None
d= 3
while d * d <= n:
if n % d == 0:
return None
d= d 2
return n
loop = range(2,1000000)
chunks = range(1,1000000,1000)
def chunker(chunk):
ret = []
r2 = chunk 1000
r1 = chunk
for k in range(r1,r2):
ret.append(prime(k))
return ret
from multiprocessing import cpu_count
from multiprocessing.dummy import Pool
from time import time as t
pool = Pool(12)
start = t()
results = pool.map(prime, loop)
print(t() - start)
pool.close()
filtered = filter(lambda score: score != None, results)
new = []
start = t()
for i in loop:
new.append(prime(i))
print(t()-start)
pool = Pool(12)
start = t()
results = pool.map_async(chunker, chunks).get()
print(t() - start)
pool.close()
Я выполнил программу, и вот где раз:
multi processing without chunks:
4.953783750534058
single thread:
5.067057371139526
multiprocessing with chunks:
5.041667222976685
Возможно, вы уже заметили, но многопроцессорная обработка не намного быстрее. У меня 6-ядерный 12-потоковый процессор AMD ryzen, поэтому я предположил, что если смогу использовать все эти потоки, то, по крайней мере, удвою производительность. Но нет. Если я посмотрю в диспетчере задач, то загрузка ЦП в среднем при использовании многопроцессорной обработки составляет 12%, в то время как однопоточный использует около 10% ЦП.
Так что же происходит? Я сделал что-то не так? Или означает ли это, что возможность обойти GIL не означает возможность использовать больше ядер? Если я не могу использовать больше ядер с многопроцессорной обработкой, как я могу это сделать?
Ответ №1:
from multiprocessing.dummy import Pool
from time import time as t
pool = Pool(12)
Из документации:
multiprocessing.dummy
копирует APImultiprocessing
, но является не более чем оболочкой вокругthreading
модуля.
Другими словами, вы все еще используете потоки, а не процессы.
Чтобы использовать процессы, сделайте from multiprocessing import Pool
это вместо этого.