NLP |用 execnet 进行并行列表处理
原文:https://www . geesforgeks . org/NLP-parallel-list-processing-with-exec net/
本文介绍了一种使用 execnet 并行处理列表的模式。这是一种函数模式,用于将列表中的每个元素映射到一个新值,使用 execnet 并行进行映射。
在下面给出的代码中,整数被简单地加倍,任何纯计算都可以被执行。给定的是模块,它将由 execnet 执行。它接收(I,arg)的二元组,假设 arg 是一个数字,然后发送回来(I,arg*2)。
代码:
if __name__ == '__channelexec__':
for (i, arg) in channel:
channel.send((i, arg * 2))
要使用此模块将列表中的每个元素加倍,请导入 plists 模块,并使用 remote_double 模块调用 plists.map() ,并将整数列表加倍。
代码:使用 plist
import plists, remote_double
plists.map(remote_double, range(10))
输出:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
map()函数是在 plists.py 中定义的。它包含一个纯模块、一个参数列表和一个可选的二元组列表,二元组由(spec,count)组成。默认规格为[('popen ',2)],这意味着用户将打开两个本地网关和通道。一旦这些通道被打开,用户就可以将它们放入 itertools 循环中,这将创建一个无限迭代器,一旦到达终点,它就会循环回到起点。
现在,每个参数都可以以参数的形式发送到一个通道进行处理,并且由于通道是循环的,所以每个通道都获得了几乎均匀的参数分布。这就是 i 进来的地方——结果返回的顺序未知,所以 i 作为列表中每个参数的索引,被传递给通道,然后返回,这样用户就可以按照原来的顺序组合结果。然后用一个多通道接收队列等待结果,并将它们插入一个与原始参数长度相同的预填充列表中。获得所有预期结果后,退出网关并返回结果,如下面给出的代码所示–
代码:
import itertools, execnet
def map(mod, args, specs =[('popen', 2)]):
gateways = []
channels = []
for spec, count in specs:
for i in range(count):
gw = execnet.makegateway(spec)
gateways.append(gw)
channels.append(gw.remote_exec(mod))
cyc = itertools.cycle(channels)
for i, arg in enumerate(args):
channel = next(cyc)
channel.send((i, arg))
mch = execnet.MultiChannel(channels)
queue = mch.make_receive_queue()
l = len(args)
# creates a list of length l,
# where every element is None
results = [None] * l
for i in range(l):
channel, (i, result) = queue.get()
results[i] = result
for gw in gateways:
gw.exit()
return results
代码:通过修改规格增加并行化
plists.map(remote_double, range(10), [('popen', 4)])
输出:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
然而,更多的并行化不一定意味着更快的处理。这取决于可用的资源,打开的网关和通道越多,需要的开销就越大。理想情况下,每个中央处理器内核应该有一个网关和通道,以获得最大的资源利用率。对任何纯模块使用 plists.map() ,只要它接收并发回 2 元组,其中 I 是第一个元素。当有一堆要处理的数字需要尽快处理时,这种模式是最有用的。
版权属于:月萌API www.moonapi.com,转载请注明出处