Совместное использование в параллельном питоне - PullRequest
5 голосов
/ 05 мая 2010

Я использую ParallelPython для разработки сценария, критичного к производительности. Я хотел бы разделить одно значение между 8 процессами, запущенными в системе. Пожалуйста, извините за тривиальный пример, но это иллюстрирует мой вопрос.

def findMin(listOfElements):
    for el in listOfElements:
        if el < min:
             min = el

import pp
min = 0
myList = range(100000)
job_server = pp.Server()
f1 = job_server.submit(findMin, myList[0:25000])
f2 = job_server.submit(findMin, myList[25000:50000])
f3 = job_server.submit(findMin, myList[50000:75000]) 
f4 = job_server.submit(findMin, myList[75000:100000]) 

Документы pp не описывают способ обмена данными между процессами. Возможно ли это?

Если это так, существует ли стандартный механизм блокировки (как в модуле потоков), чтобы подтвердить, что одновременно выполняется только одно обновление?

l = Lock()
if(el < min):
     l.acquire
     if(el < min):
         min = el
     l.release

Я понимаю, что мог бы хранить локальные минуты и сравнивать 4 в главном потоке, как только вернул, но, разделяя значение, я мог бы сделать лучшее сокращение моего двоичного дерева BFS и потенциально сохранить много повторений цикла.

1011 * Благодарения и *

Jonathan

Ответы [ 4 ]

1 голос
/ 14 мая 2010

Parallel Python запускает подфункции в разных процессах, поэтому нет общей памяти, что означает, что вам не следует использовать общее значение. Пример обратного вызова, упомянутый clackle, берет результаты каждой функции и объединяет их в функцию обратного вызова, которая работает в исходном процессе. Чтобы использовать его правильно, вы должны сделать что-то подобное; в приведенном примере вы будете вычислять локальные минимумы и использовать функцию обратного вызова, чтобы найти минимум всех подрезультатов. Надеюсь, в вашем реальном случае вы можете сделать что-то подобное.

1 голос
/ 09 мая 2010

На самом деле, есть пример на http://www.parallelpython.com/content/view/17/31/#CALLBACK, и они просто используют блокировки от модуля потока.

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

0 голосов
/ 13 мая 2010

Вы не будете сохранять никакие итерации, разделяя значение, вам нужно прочитать хотя бы один раз каждый элемент из списка.Более того, это будет медленнее, поскольку вам нужно блокировать каждый раз, когда вы используете общее значение.

В вашем случае, если вы хотите повысить производительность, вы должны вычислить мин для каждой части отдельно и сравнить эти результатыосновной поток.

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

0 голосов
/ 05 мая 2010

Я не уверен насчет модуля PP, но вы всегда можете сохранить наименьшее значение в файле с нулями. Единственное, что меня беспокоит, так это то, что вы потратите большую часть своего времени на приобретение и снятие блокировки. Единственное исключение будет, если ваша операция el < min отнимает много времени.

Я бы на самом деле сказал, что ваша техника "слияния" - это, вероятно, верный путь.

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

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