2015-11-18 2 views
14

Я пытаюсь запустить параллельный цикл на простом примере.
Что я делаю неправильно?Написание параллельного цикла

from joblib import Parallel, delayed 
import multiprocessing 

def processInput(i): 
     return i * i 

if __name__ == '__main__': 

    # what are your inputs, and what operation do you want to 
    # perform on each input. For example... 
    inputs = range(1000000)  

    num_cores = multiprocessing.cpu_count() 

    results = Parallel(n_jobs=4)(delayed(processInput)(i) for i in inputs) 

    print(results) 

Проблема с кодом является то, что при выполнении под средой Windows, в Python 3, он открывает num_cores экземпляров питона для выполнения параллельных заданий, но только один активен. Это не должно быть так, так как активность процессора должна быть на 100% вместо 14% (в i7-8 логических ядрах).

Почему дополнительные экземпляры ничего не делают?

+0

Вы получили сообщение об ошибке? Это отлично работает для меня .... Отступы должны быть 4 пробела вместо одного ... –

+0

У меня такая же проблема. Проблема в том, что код работает только на одном ядре, а не на n-ядрах. –

ответ

17

Продолжающиеся по вашей просьбе, чтобы обеспечить рабочий MultiProcessing код, я предлагаю вам использовать pool_map (если отложенная функциональность не важна), я приведу вам пример, если вы работаете над python3, стоит упомянуть, что вы можете использовать starmap. Также стоит упомянуть, что вы можете использовать map_sync/starmap_async, если порядок возвращаемых результатов не должен соответствовать порядку ввода.

import multiprocessing as mp 

def processInput(i): 
     return i * i 

if __name__ == '__main__': 

    # what are your inputs, and what operation do you want to 
    # perform on each input. For example... 
    inputs = range(1000000) 
    # removing processes argument makes the code run on all available cores 
    pool = mp.Pool(processes=4) 
    results = pool.map(processInput, inputs) 
    print(results) 
+0

Мне нравится простота этого, поэтому я попробовал. Я получаю TypeError: не может сериализовать объект _io.TextIOWrapper. Моя функция сложная, и у меня нет времени погрузиться в нее, просто комментарий о том, есть ли у вас сложная функция, это может не сработать. – Nick

+0

Сериализация является важной частью каждой программы многопроцессорности. Чтобы попытаться смягчить такие проблемы, я рекомендую изучить вашу сложную функцию и проверить, какая часть ее действительно нуждается в многопроцессорном решении, и попытаться отключить ее от сложной функции, это облегчит сериализацию и даже сделает ее ненужной. – Fanchi

2

В Windows многопроцессорный модуль использует метод «spawn» для запуска нескольких процессов интерпретатора python. Это относительно медленно. Параллельно пытается быть умным для запуска кода. В частности, он пытается настроить размер партии, поэтому для выполнения партии требуется около половины секунды. (См batch_size аргумент в https://pythonhosted.org/joblib/parallel.html)

Ваша processInput() функция работает так быстро, что Parallel определяет, что это быстрее, чтобы запустить работу последовательно на одном процессоре, чем раскручивать несколько интерпретаторов питона и запустить код параллельно.

Если вы хотите заставить свой пример работать на нескольких ядрах, попробуйте установить batch_size на 1000 или сделать processInput() более сложным, поэтому выполнение занимает больше времени.

Edit: Работа на пример окна показывает несколько процессов в использовании (я использую Windows 7):

from joblib import Parallel, delayed 
from os import getpid 

def modfib(n): 
    # print the process id to see that multiple processes are used, and 
    # re-used during the job. 
    if n%400 == 0: 
     print(getpid(), n) 

    # fibonacci sequence mod 1000000 
    a,b = 0,1 
    for i in range(n): 
     a,b = b,(a+b)%1000000 
    return b 

if __name__ == "__main__": 
    Parallel(n_jobs=-1, verbose=5)(delayed(modfib)(j) for j in range(1000, 4000)) 
+0

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