Неожиданная производительность при использовании ProcessPool в Python - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь использовать ProcessPoolExecutor из пакета Python concurrent.futures.Тем не менее, я достигаю очень низкой производительности и не могу понять, почему.

Мой код выглядит следующим образом:

import time
from itertools import product
from concurrent.futures import ProcessPoolExecutor

def myfunc(bundle):
    "A simple function which takes some time to complete."
    clock_start = time.clock()
    for _ in range(*bundle):
        lst = [[0., 0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.85, 0.9, 0.95, 1.0]
                for x in range(6)]
        res = [t for t in product(*lst) if abs(sum(t) - 1.) < 1e-8]
    clock_elapsed = time.clock() - clock_start
    return clock_elapsed

def parallel(bundles, nworkers):
    "A function to dispatch execution between different workers."
    with ProcessPoolExecutor(max_workers=nworkers) as executor:
        execgen = executor.map(myfunc, bundles)
        total_clock = 0.
        for _clock in execgen:
            total_clock += _clock
    print("mean iteration: {:.3f} s".format(total_clock / bundles[-1][-1]))

(Функция myfunc не интересна как таковая, но я ожидаю выполнениябыть линейным по количеству итераций).

Когда я тестирую этот код на своем компьютере (Python 3.6, Debian, 8 CPU), я получаю следующие результаты:

>>> parallel([(0, 60)], 1)
mean iteration: 3.660 s

>>> parallel([(0, 30), (30, 60)], 2)
mean iteration: 3.747 s

>>> parallel([(0, 20), (20, 40), (40, 60)], 3)
mean iteration: 4.413 s

>>> parallel([(0, 10), (10, 20), (20, 30), (30, 40), (40, 50), (50, 60)], 6)
mean iteration: 7.534 s

ИтакОчевидно, что разделение выполнения между 6 работниками означает, что одна итерация занимает в среднем вдвое больше времени, чем с одним работником.Поскольку итерация должна быть полностью независимой, я не могу понять, почему это так?

1 Ответ

0 голосов
/ 19 апреля 2019

Ваш код не соответствует вашей мотивации.Во всех 4 прогонах вашего кода ваш total_clock всегда равен sum времени завершения всего вычисления 60 независимо от того, сколько ядер вы используете.Теоретически, все 4 прогона должны возвращать одинаковое значение без учета затрат на многопроцессорность (связь ...).Очевидно, что это зависит от фактической вычислительной нагрузки независимо от того, где (на каком ядре) она выполняется.

Я считаю, что вы хотите доказать, что многопроцессорность - это экономия времени.Обновите код

print("mean iteration: {:.3f} s".format(total_clock / nworkers)) 

Или просто почувствуйте и сравните с человеком интуитивно понятное время, прошедшее до того, как эти 4 прогона вернутся.

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