Я экспериментирую с многопроцессорным модулем Python 3, и у меня есть следующий код, который читает файл, содержащий число в каждой строке, и печатает факторизацию каждого числа:
import multiprocessing
import sys
NUM_PROCESSES = 4
CHUNK_SIZE = 20
def factor(n):
#Return a list of factors of n
factors = []
#factor out 2's
while n % 2 == 0:
factors.append(2)
n //= 2
factor = 3
while n > 1:
if n % factor == 0:
factors.append(factor)
n //= factor
else:
factor += 2
return factors
def process_line(line):
#process an input file line
number = int(line)
factorization = '*'.join(str(x) for x in factor(number))
return f'{number} = {factorization}\n'
if __name__ == '__main__':
with open('input.txt') as f:
with multiprocessing.Pool(NUM_PROCESSES) as pool:
processed = pool.imap(process_line, f, CHUNK_SIZE)
sys.stdout.writelines(processed)
Я запускаю это насистема Linux с 2 физическими ядрами с гиперпоточностью, всего 4 виртуальных ядра.Я протестировал этот скрипт на файле, содержащем 10 000 случайных чисел от 2 до 1 000 000, и измерил его производительность с помощью команды time
.
Когда NUM_PROCESSES
равен 1, я получаю результат:
real 0m26.997s
user 0m26.979s
sys 0m0.077s
Когда NUM_PROCESSES
равно 2, я получаю:
real 0m13.477s
user 0m26.809s
sys 0m0.048s
Пока это то, что я ожидал - добавление еще одного процесса сокращает время выполнения почти ровно пополам, в то время как общее время процессора остаетсятот же самый.Но когда NUM_PROCESSES
равно 4, я получаю:
real 0m14.598s
user 0m56.703s
sys 0m0.059s
Мало того, что время выполнения не уменьшилось, а увеличилось на 1 секунду, даже несмотря на то, что время ЦП удвоилось.В основном это означает, что каждый виртуальный ЦП работал на половине скорости физического ЦП, поэтому при работе на всех 4 виртуальных ЦП не было никакого выигрыша в производительности.Изменение CHUNK_SIZE
не оказывает существенного влияния на производительность, если я установлю его на 1 или 2500.Использование map()
вместо imap()
также ничего не меняет.
Насколько я понимаю, виртуальные многопоточные ядра не дают таких же преимуществ по производительности, как дополнительные физические ядра, но они все равно должны предлагать некоторые улучшение, верно?Почему тогда производительность скрипта не улучшилась?