0

Я пытаюсь следующий код:Почему pool.map медленнее обычной карты?

import multiprocessing 
import time 
import random 

def square(x): 
    return x**2 

pool = multiprocessing.Pool(4) 

l = [random.random() for i in xrange(10**8)] 

now = time.time() 
pool.map(square, l) 
print time.time() - now 

now = time.time() 
map(square, l) 
print time.time() - now 

и версия pool.map последовательно проходит несколько секунд медленнее, чем обычный map версии (19 секунд против 14 секунд).

Я посмотрел на вопросы: Why is multiprocessing.Pool.map slower than builtin map? и multiprocessing.Pool() slower than just using ordinary functions и они, кажется, приписывают его либо IPC над головой или диск насыщения, но я чувствую, как в моем примере это те, очевидно, не проблема; Я не пишу/ничего не читаю на диске с диска, и вычисление достаточно долгое, что кажется, что накладные расходы IPC должны быть небольшими по сравнению с общим временем, сохраненным многопроцессорной обработкой (я оцениваю это, поскольку я выполняю работу на 4 ядра вместо 1, я должен сократить время вычисления с 14 секунд до 3,5 секунд). Я не насыщаю свой процессор, я не думаю; проверка cat /proc/cpuinfo показывает, что у меня 4 ядра, но даже когда я многопроцесс только для 2 процессов, он все еще медленнее, чем обычная функция карты (и даже медленнее, чем 4 процесса). Что еще может замедлить многопроцессорную версию? Я не понимаю, как накладные расходы IPC?

Если это уместно, этот код написан на Python 2.7, и моя ОС Linux Mint 17,2

+0

Сколько стоит l? –

+0

@PeterWood: Из кода видно, что у него есть элементы '10 ** 8'. – BrenBarn

+0

Разве это воссоздано в каждом процессе? –

ответ

2

pool.map разбивает список на N рабочих места (где N является размером списка) и отправляет те процессы ,

Работа один процесс делает это показано в коде:

def square(x): 
    return x**2 

Эта операция занимает очень мало времени на современных процессорах, независимо от того, насколько большой номер.

В вашем примере вы создаете огромный список и выполняете нерелевантную операцию над каждым элементом. Разумеется, накладные расходы IPC будут больше по сравнению с обычной функцией map, которая оптимизирована для быстрого цикла.

Чтобы увидеть, как ваш пример работает так, как вы ожидаете, просто добавьте вызов квадратной функции time.sleep(0.1). Это имитирует долговременную задачу. Конечно, вы можете уменьшить размер списка, иначе он будет завершен.

 Смежные вопросы

  • Нет связанных вопросов^_^