Сравнение на мултипроцесорния модул и пиро?

Използвам pyro за основно управление на паралелни задачи в изчислителен клъстер. Току-що се преместих в клъстер, където ще отговарям за използването на всички ядра на всеки изчислителен възел. (При предишни клъстери всяко ядро ​​е било отделен възел.) Модулът мултипроцесор на python изглежда като подходящ за това. Забелязвам, че може да се използва и за комуникация с отдалечен процес. Ако някой е използвал и двете рамки за комуникация с отдалечени процеси, ще съм благодарен да чуя как се подреждат една срещу друга. Очевидното предимство на мултипроцесорния модул е, че той е вграден от 2.6. Освен това ми е трудно да кажа кое е по-добро.


person Alex Coventry    schedule 23.07.2009    source източник


Отговори (1)


РЕДАКТИРАНЕ: Променям отговора си, за да избегнете болка. мултипроцесирането е незряло, документите на BaseManager са НЕПРАВИЛНИ и ако сте обектно-ориентиран мислител, който иска да създава споделени обекти в движение по време на изпълнение, ИЗПОЛЗВАЙТЕ PYRO ИЛИ ЩЕ СЕРИОЗНО СЪЖАЛЯВАМЕ! Ако просто правите функционално програмиране, използвайки споделена опашка, която регистрирате предварително, както всички глупави примери, ДОБРИ ЗА ВАС.

Кратък отговор

Многопроцесорна обработка:

  • Чувства се неудобно да прави обектно-ориентирани отдалечени обекти
  • Лесно прохладно крипто (authkey)
  • През мрежа или просто междупроцесна комуникация
  • Без допълнителни проблеми за неймсървъра като в Pyro (има начини да се заобиколи това)
  • Редактиране: Не могат да се „регистрират“ обекти, след като мениджърът е създаден!!??
  • Редактиране: Ако сървърът не е стартиран, клиентът хвърля някакво изключение „Невалиден аргумент“, вместо просто да каже „Неуспешно свързване“ WTF!?
  • Редактиране: Документацията на BaseManager е неправилна! Няма метод "старт"!?!
  • Редактиране: Много малко примери за това как да го използвате.

Пиро:

  • Прости отдалечени обекти
  • Само мрежови комуникации (завъртане, ако е само локално)
  • Редактиране: Това нещо просто РАБОТИ и харесва обектно-ориентирано споделяне на обекти, което ме кара да го ХАРЕСАМ
  • Редактиране: Защо ТОВА не е част от стандартната библиотека вместо онзи мултипроцесор, който се опита да го копира и се провали мизерно?

Редактиране: Първият път, когато отговорих на това, току-що се бях потопил в многопроцесорната обработка 2.6. В кода, който показвам по-долу, класът Texture е регистриран и споделен като прокси, но атрибутът „data“ в него НЕ е такъв. Така че познайте какво се случва, всеки процес има отделно копие на атрибута "данни" вътре в проксито на текстурата, въпреки това, което може да очаквате. Току-що прекарах безброй часове, опитвайки се да разбера как е добър модел за създаване на споделени обекти по време на изпълнение и продължих да се натъквам на тухлени стени. Беше доста объркващо и разочароващо. Може би това е само аз, но гледайки оскъдните примери, които хората са опитвали, не изглежда така.

Трябва да взема болезненото решение да се откажа от многопроцесорната библиотека и да предпочета Pyro, докато мултипроцесорът стане по-зрял. Докато първоначално бях развълнуван да науча многопроцесорната обработка да бъде вградена в Python, сега съм напълно отвратен от нея и бих предпочел да инсталирам пакета Pyro много пъти с радост, че такава красива библиотека съществува за Python.

Дълъг отговор

Използвал съм Pyro в минали проекти и съм много доволен от него. Също така започнах да работя с многопроцесорно ново във 2.6.

С многопроцесорната обработка открих, че е малко неудобно да позволявам споделени обекти да бъдат създавани според нуждите. Изглежда, че в младостта си мултипроцесорният модул е ​​бил по-скоро насочен към функционално програмиране, а не към обектно-ориентирано. Това обаче не е съвсем вярно, защото е възможно да се направи, просто се чувствам ограничен от обажданията за „регистриране“.

Например:

manager.py:

from multiprocessing import Process
from multiprocessing.managers import BaseManager

class Texture(object):
   def __init__(self, data):
        self.data = data

   def setData(self, data):
      print "Calling set data %s" % (data)
      self.data = data

   def getData(self):
      return self.data

class TextureManager(BaseManager):
   def __init__(self, address=None, authkey=''):
      BaseManager.__init__(self, address, authkey)
      self.textures = {}

   def addTexture(self, name, texture):
      self.textures[name] = texture

   def hasTexture(self, name):
      return name in self.textures

server.py:

from multiprocessing import Process
from multiprocessing.managers import BaseManager
from manager import Texture, TextureManager

manager = TextureManager(address=('', 50000), authkey='hello')

def getTexture(name):
   if manager.hasTexture(name):
      return manager.textures[name]
   else:
      texture = Texture([0]*100)
      manager.addTexture(name, texture)
      manager.register(name, lambda: texture)

TextureManager.register("getTexture", getTexture)


if __name__ == "__main__":
   server = manager.get_server()
   server.serve_forever()

client.py:

from multiprocessing import Process
from multiprocessing.managers import BaseManager
from manager import Texture, TextureManager

if __name__ == "__main__":
   manager = TextureManager(address=('127.0.0.1', 50000), authkey='hello')
   manager.connect()
   TextureManager.register("getTexture")
   texture = manager.getTexture("texture2")
   data = [2] * 100
   texture.setData(data)
   print "data = %s" % (texture.getData())

Неудобството, което описвам, идва от server.py, където регистрирам функция getTexture, за да извлека функция с определено име от TextureManager. Докато разглеждам това, неудобството вероятно може да бъде премахнато, ако направя TextureManager споделяем обект, който създава/извлича споделяеми текстури. Мх, още играя, но схващате идеята. Не си спомням да съм срещал тази неудобство при използване на пиро, но вероятно има решение, което е по-чисто от горния пример.

person manifest    schedule 23.12.2009