2010-10-01 21 views
35

Python 2.7'de paralel işlem yapan basit bir kod nedir? İnternette bulduğum tüm örnekler kıvrımlı ve gereksiz kodları içeriyor.Python'da Paralel İşleme

Her bir çekirdek (4) üzerinde 1 tamsayı katlayabileceğim basit bir kaba kuvvet tamsayısı faktoring programını nasıl yapabilirim? Benim gerçek programım muhtemelen sadece 2 çekirdeğe ihtiyaç duyar ve bilgi paylaşmaya ihtiyaç duyar.

onlar piton gel beri dolayısıyla ben thread ve/veya multiprocessing kütüphaneleri kullanmak istiyorum, ben paralel piton ve diğer kütüphaneler var olduğunu biliyorum, ama minimumda kullanılan kütüphanelerin sayısını tutmak istiyoruz

+0

başka bir yol, ben burada açıkladım geçerli: - [Asgari aktif dişli İşlemler] [1] [1]: http://stackoverflow.com/a/32337959/4850220 –

cevap

29

Python'da paralel işlemeye başlamak için basit ve basit bir yol, yalnızca ortak işlemlemede havuz eşlemesidir - her zamanki python haritaları gibi, ancak bireysel işlev çağrıları farklı işlem sayılarına yayılır.

Faktoring bu güzel örneğidir - Eğer kaba kuvvet mevcut tüm görevleri üzerinde yayılan tüm bölünmeleri kontrol edin:

from multiprocessing import Pool 
import numpy 

numToFactor = 976 

def isFactor(x): 
    result = None 
    div = (numToFactor/x) 
    if div*x == numToFactor: 
     result = (x,div) 
    return result 

if __name__ == '__main__': 
    pool = Pool(processes=4) 
    possibleFactors = range(1,int(numpy.floor(numpy.sqrt(numToFactor)))+1) 
    print 'Checking ', possibleFactors 
    result = pool.map(isFactor, possibleFactors) 
    cleaned = [x for x in result if not x is None] 
    print 'Factors are', cleaned 

Bu bana

Checking [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] 
Factors are [(1, 976), (2, 488), (4, 244), (8, 122), (16, 61)] 
+2

Yukarıdaki işleri eklemeliyim, ama muhtemelen baştan başa olduğunuzdan (paralel harita + işlev çağrısı), küçük bir hesaplamak için şaşırtıcı bir performans sergiliyor. iş miktarı (biraz integer aritmetiği). Okuyucunun, daha fazla bölümün üstünden nasıl amorti edileceğini düşünmek için bir alıştırma olarak bırakacağım - örneğin, yukarıdaki kodun nasıl değiştirileceği, böylece "isFactor" un bir kısım bölümler için bir kez çağrılması. –

8

mincemeat bulduğum en basit harita/azaltma uygulamasıdır. Ayrıca, bağımlılıklar üzerinde çok hafif - bu tek bir dosya ve standart kütüphaneye sahip her şeyi yapıyor.

+0

ilginç ... içine bakacağım – calccrypto

+0

Gerçekten ne aradığım değildi gerçekten – calccrypto

+1

@calccrypto Neden olmasın? Mineceminin neden mükemmel olmadığını bilmek başkalarının daha iyi bir çözüm bulmasına yardımcı olabilir. –

1

verir ben katılıyorum Pool kullanarak Standart kütüphanede kalmak istiyorsanız, multiprocessing'dan muhtemelen en iyi yoldur. Paralel işlemenin diğer türlerini yapmakla ilgileniyorsanız, ancak yeni bir şey öğrenmeyle ilgileniyorsanız (yani multiprocessing ile aynı arabirimi kullanarak), paralel haritalar çeşitli formları sağlar ve multiprocessing ile hemen hemen aynı arabirimi olan pathos deneyebilirsiniz yapar. Ayrıca

Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import numpy 
>>> numToFactor = 976 
>>> def isFactor(x): 
... result = None 
... div = (numToFactor/x) 
... if div*x == numToFactor: 
...  result = (x,div) 
... return result 
... 
>>> from pathos.multiprocessing import ProcessingPool as MPool 
>>> p = MPool(4) 
>>> possible = range(1,int(numpy.floor(numpy.sqrt(numToFactor)))+1) 
>>> # standard blocking map 
>>> result = [x for x in p.map(isFactor, possible) if x is not None] 
>>> print result 
[(1, 976), (2, 488), (4, 244), (8, 122), (16, 61)] 
>>> 
>>> # asynchronous map (there's also iterative maps too) 
>>> obj = p.amap(isFactor, possible)     
>>> obj 
<processing.pool.MapResult object at 0x108efc450> 
>>> print [x for x in obj.get() if x is not None] 
[(1, 976), (2, 488), (4, 244), (8, 122), (16, 61)] 
>>> 
>>> # there's also parallel-python maps (blocking, iterative, and async) 
>>> from pathos.pp import ParallelPythonPool as PPool 
>>> q = PPool(4) 
>>> result = [x for x in q.map(isFactor, possible) if x is not None] 
>>> print result 
[(1, 976), (2, 488), (4, 244), (8, 122), (16, 61)] 

, pathos mpi4py çalışır pyina denilen aynı arayüzü ile kardeş paketi, var ama MPI çalıştırmak ve birkaç schedulers kullanılarak çalıştırılabilir paralel haritalar birlikte açar.

Diğer bir avantajı, pathos'un standart python'a göre çok daha iyi bir serileştirici ile birlikte gelmesidir, bu yüzden multiprocessing'dan çok çeşitli işlevleri ve diğer şeyleri serileştirmede çok daha yeteneklidir. Ve tercümandan her şeyi yapabilirsin.

>>> class Foo(object): 
... b = 1 
... def factory(self, a): 
...  def _square(x): 
...  return a*x**2 + self.b 
...  return _square 
... 
>>> f = Foo() 
>>> f.b = 100 
>>> g = f.factory(-1) 
>>> p.map(g, range(10)) 
[100, 99, 96, 91, 84, 75, 64, 51, 36, 19] 
>>> 

burada kodu alma: Burada https://github.com/uqfoundation