NLP | execnet ile paralel liste işleme

| | | | | | | | | | | | | | | | | | | |

Aşağıdaki kodda, tamsayılar basitçe ikiye katlanır, herhangi bir temiz hesaplama yapılabilir. Bu, execnet tarafından yürütülecek modüldür. 2 demet (i, arg) alır, arg`nin bir sayı olduğunu varsayar ve geri gönderir (i, arg * 2).

Kod:

if __ name__ = = `__channelexec__` :

için (i, arg) kanalında:

channel.send ((i, arg * 2 ))

Kullanmak için listedeki her bir öğeyi ikiye katlamak için bu modül, plist modülünü içe aktarın ve plist .map () `i çağırın bir remote_double modülü ve ikiye katlanacak bir tamsayı listesi.

Kod: Plist`i kullanma


import plist, remote_double

plist. map (remote_double, aralık ( 10 ))

Çıktı:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 

Harita ( ) işlevi plists.py`de tanımlanmıştır. Saf bir modül, bir argüman listesi ve isteğe bağlı iki demetli bir liste (spec, count) alır. Varsayılan olarak, özellikler [(' popen ', 2)] kullanılır; bu, kullanıcının iki yerel ağ geçidi ve kanal açacağı anlamına gelir. Bu kanallar açıldıktan sonra, kullanıcı bunları bir itertools döngüsüne yerleştirebilir, bu da sona ulaştığı anda başa dönen sonsuz bir yineleyici oluşturur.

Artık her argüman argüman olarak gönderilebilir. işlem için boruya ve kanallar döngüsel olduğundan, her kanal neredeyse eşit bir argüman dağılımı alır. İşte tam bu noktada Ben — sonuçların döndürülme sırası bilinmiyor, bu nedenle listedeki her bağımsız değişkenin dizini olarak i , kullanıcının sonuçları orijinal sırayla birleştirebilmesi için kanala ve kanaldan iletilir. . Ardından, MultiChannel alma kuyruğu ile sonuçları bekleyin ve bunları orijinal argümanlarla aynı uzunlukta önceden doldurulmuş bir listeye ekleyin. Beklenen tüm sonuçları aldıktan sonra, ağ geçitlerinden çıkın ve sonuçları aşağıdaki kodda gösterildiği gibi döndürün —

Kod:


import itertools, execnet

def harita (mod, argümanlar, özellikler = [( `popen` , 2 )]):

ağ geçitleri = []

kanallar = []

için spesifikasyon, sayım in özellikler:

için i içinde aralık (sayım):

gw = execnet.makegateway (spec)

gateways.append (gw )

kanallar.append (gw.remote_exec (mod))


döngü = itertools.cycle (kanallar)


< kod sınıfı = "tanımsız boşluklar"> for i, arg numaralandır (args):

kanal = sonraki (döngü )

channel.send ((i, arg))

mch = execnet.MultiChannel (kanallar)

kuyruk = mch.make_receive_queue ()

l = len (args)

# l uzunluğunda bir liste oluşturur,

# burada her öğe Yoktur

sonuçlar = [ Yok ] * l

for i aralığında (l):

kanal, (i, sonuç) = tail.get ()

sonuçlar [i] = sonuç

için gw in ağ geçitleri:

gw.exit()

dönüş sonuçlar

Kod: Spesifikasyonu değiştirerek paralelleştirmeyi artırın


plistler. eşleme (remote_double, aralık ( 10 ), [( `popen` , 4 )])

Çıktı:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 

Ancak, artık paralelleştirmenin olmaması, mutlaka daha hızlı işleme anlamına gelir. Mevcut kaynaklara bağlıdır ve ne kadar çok ağ geçidi ve kanal açılırsa, ek yük o kadar artar. İdeal olarak, kaynak kullanımını en üst düzeye çıkarmak için CPU çekirdeği başına bir ağ geçidi ve kanal olmalıdır. plist.map () `i herhangi bir temiz modülle birlikte 2 tuple alıp geri gönderdiği sürece kullanın, burada i ilk öğedir. Bu kalıp, mümkün olduğunca çabuk işlemek için işlenmesi gereken çok sayıda sayı olduğunda en kullanışlıdır.