Python multiprocessing.Pool: Почему добавление дополнительных процессов не улучшает производительность в многопоточной системе? - PullRequest
0 голосов
/ 19 октября 2018

Я экспериментирую с многопроцессорным модулем 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() также ничего не меняет.

Насколько я понимаю, виртуальные многопоточные ядра не дают таких же преимуществ по производительности, как дополнительные физические ядра, но они все равно должны предлагать некоторые улучшение, верно?Почему тогда производительность скрипта не улучшилась?

1 Ответ

0 голосов
/ 19 октября 2018

(извините, я пока не могу добавить комментарий) Можете ли вы показать вывод lscpu?Создание слишком большого количества процессов / потоков приведет к переключению контекста .Когда вы запускаете это и используете htop, все ли ядра на 100%?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...