почему многопроцессорная обработка не использует все мои ядра

#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 копирует API multiprocessing , но является не более чем оболочкой вокруг threading модуля.

Другими словами, вы все еще используете потоки, а не процессы.

Чтобы использовать процессы, сделайте from multiprocessing import Pool это вместо этого.