2010-01-20 2 views
0

Как можно запускать несколько вычислений параллельно, останавливая их при первом возвращении?Как можно запускать несколько вычислений параллельно, останавливая их при первом возвращении? [Python]

Приложение, которое я имею в виду, следующее: существует несколько способов вычисления определенного значения; каждый метод принимает различное количество времени в зависимости от параметров функции; путем параллельного запуска вычислений, самый быстрый расчет будет автоматически «выбран» каждый раз, а остальные вычисления будут остановлены.

Теперь, есть некоторые «детали», которые делают более трудным этот вопрос:

  • Параметры функции должны быть рассчитаны включают функции (которые вычисляются из точек данных, они не являются функции модуля верхнего уровня). Фактически, вычисление представляет собой свертку двух функций. Я не уверен, как такие параметры функции могут быть переданы подпроцессу (они не подбираются).
  • У меня нет доступа ко всем расчетным кодам: некоторые вычисления выполняются внутри Scipy (возможно, через Fortran или C-код). Я не уверен, что потоки предлагают нечто похожее на сигналы терминации, которые могут быть отправлены процессам.

Это что-то, что Python может сделать относительно легко?

ответ

1

Я бы посмотрел на модуль multiprocessing, если вы еще этого не сделали. Он предлагает способ разгрузки задач для отдельных процессов, предоставляя вам простой, как и интерфейс, threading.

Он предоставляет те же самые примитивы, что и в модуле threading, например пулы работников и очереди для передачи сообщений между вашими задачами, но это позволяет обойти проблему GIL, поскольку ваши задачи фактически выполняются в отдельные процессы.

Фактическая семантика того, что вы хотите, весьма специфична, поэтому я не думаю, что есть подпрограмма, которая подходит к счету из коробки, но вы можете наверняка сбить ее с ног.

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

+0

'multiprocessing' отлично работает для этой более сложной ситуации! На самом деле мне удалось передать * не-pickleable функцию * в качестве аргумента для вычислений! Хотя «многопроцессорность» была просто удобной оболочкой вокруг «подпроцесса» и «потоковой обработки», но мне кажется, что «многопроцессорность» обеспечивает гораздо больше. – EOL

+0

PS: Я проверил, что оба ядра были полностью использованы вычислениями. – EOL

0

Из-за блокировки глобального интерпретатора вам будет трудно получить такое ускорение таким образом. На самом деле даже многопоточные программы в Python работают только на одном ядре. Таким образом, вы просто выполняете N процессов в 1/N раз быстрее. Даже если вы закончите за половину времени остальных, вы все равно потеряете время в общей картине.

+0

Да, именно поэтому я упомянул и подпроцессы. :) – EOL

0

Процессы можно запускать и убивать тривиально.

Вы можете сделать это.

import subprocess 
watch = [] 
for s in ("process1.py", "process2.py", "process3.py"): 
    sp = subprocess.Popen(s) 
    watch.append(sp) 

Теперь вы просто ждете одного из них, чтобы закончить. Когда человек закончит, убейте других.

import time 
winner= None 
while winner is None: 
    time.sleep(10) 
    for w in watch: 
     if w.poll() is not None: 
      winner= w 
      break 
for w in watch: 
    if w.poll() is None: w.kill() 

Это процессы, а не потоки. Нет соображений GIL. Заставить операционную систему планировать их; это то, что он делает лучше всего.

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

+0

Да, но дело в том, что параметры программы включают в себя * функции *, которые вычисляются «на лету» (они не являются функциями верхнего уровня в модуле и поэтому не разборчивы). Как можно обрабатывать подпроцессы? – EOL

+0

@EOL: Что? Вы абсолютно должны иметь возможность написать автономный скрипт python, который даст ответ в одну сторону, не так ли? Напишите каждый вариант как отдельный сценарий. Получите ваши параметры из файла конфигурации или что-то, что вы просто «импортируете». Не пытайтесь передать вещи через интерфейс командной строки для подпроцессов. –

+0

@S. Лотт: Интересная идея. Тем не менее, параметры вычисления - это числовые функции, которые относительно дорого перестраиваются из простых файлов параметров, поэтому этот подход «конфигурационного файла» замедляет работу. (В частности, вычисление выполняет свертку функций, которые интерполируются и экстраполируются из многих точек данных. Каждый процесс должен будет повторить интерполяцию/экстраполяцию, нет?) Я надеялся, что Python будет более сильным, чем это. :) – EOL