NLP | execnet과 병렬로 목록 처리

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

아래 코드에서 정수는 단순히 2배이며 모든 깨끗한 계산을 수행할 수 있습니다. execnet이 실행할 모듈입니다. 2개의 튜플(i, arg)을 수신하고 arg가 숫자라고 가정하고 다시 보냅니다(i, arg * 2).

코드:

<표 테두리 = "0" cellpadding = "0" cellspacing = "0">

if <코드 클래스 = "일반"> __ 이름__ <코드 클래스 = "키워드"> = <코드 클래스 = "키워드" > = <코드 클래스 = "문자열"> `__channelexec__` :

for (i, arg) 채널:

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

사용하려면 이 모듈을 사용하여 목록의 각 항목을 두 배로 늘리고 plists 모듈을 가져오고 plists .map () wi remote_double 모듈 및 두 배로 늘릴 정수 목록입니다.

코드: plist 사용


가져오기 plists, remote_double

plists. 지도 (remote_double, 범위 ( <코드 클래스 = "값"> 10 <코드 클래스 = "일반">))

출력:

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

지도( ) 함수는 plists.py에 정의되어 있습니다. 순수 모듈, 인수 목록 및 (spec, count)의 선택적 2-튜플 목록이 필요합니다. 기본적으로 사양은 [(' popen ', 2)] 사용되며, 이는 사용자가 두 개의 로컬 게이트웨이와 채널을 열 수 있음을 의미합니다. 이 파이프가 열리면 사용자는 itertools 루프에 배치할 수 있습니다. 이 루프는 끝에 도달하는 즉시 처음으로 돌아가는 무한 반복자를 생성합니다.

이제 각 인수를 인수로 보낼 수 있습니다. 처리를 위해 파이프에 연결하고 채널이 주기적이기 때문에 각 채널은 인수의 거의 동일한 분포를 받습니다. 나는 여기에서 — 결과가 반환되는 순서를 알 수 없으므로 사용자가 결과를 원래 순서로 결합할 수 있도록 목록에 있는 각 인수의 색인으로 i 가 채널로 전달되고 채널에서 전달됩니다. . 그런 다음 MultiChannel 수신 대기열이 있는 결과를 기다리고 원래 인수와 동일한 길이의 미리 채워진 목록에 삽입합니다. 모든 예상 결과를 얻은 후 게이트웨이를 종료하고 —

코드:


아래 코드와 같이 결과를 반환합니다.

가져오기 itertools, execnet

def 지도 (모드, 인수, 사양 = [( <코드 클래스 = "문자열"> `팝업` <코드 클래스 ="일반 ">, <코드 클래스 ="값 "> 2 )]):

게이트웨이 < 코드 클래스 ="키워드 "> = <코드 클래스 ="일반 "> []

<코드 클래스 ="정의되지 않은 공백 "> <코드 클래스 = "일반 "> 채널 = []

사양, 개수 사양:

for i in 범위 (개수):

gw < 코드 클래스 = "키워드"> = <코드 클래스 = "일반"> execnet.makegateway(사양)

<코드 클래스 = "일반"> gateways.append(gw )

channel.append (gw.remote_exec (mod))


순환 <코드 클래스 = "키워드"> = <코드 클래스 = "일반"> itertools.cycle(채널)


for i, arg in 열거 (args):

채널 = 다음 (cyc)

channel.send ((i, arg))

<코드 클래스 = "일반"> mch <코드 클래스 = "키워드"> = <코드 클래스 = "일반" > execnet.MultiChannel(채널)

대기열 = mch.make_receive_queue()

l = <코드 클래스 ="함수 "> len <코드 클래스 ="일반 "> (인수)

<코드 클래스 = "comments"> # 길이가 l인 목록을 생성합니다.

# 각 요소가 None인 경우

결과 = [ <코드 클래스 = "color1"> 없음 <코드 클래스 = "일반">] <코드 클래스 = "키워드"> * l

for i 범위 (l):

채널, (i, result) = queue.get ()

결과 [i] = <코드 클래스 = "일반 "> 결과

for gw in 게이트웨이:

gw.exit ()

반환 결과

코드: 사양을 변경하여 병렬화 증가


plists. 지도 (remote_double, 범위 ( <코드 클래스 = "값"> 10 <코드 클래스 = "일반">), [( <코드 클래스 = "문자열"> `팝업` <코드 클래스 = "일반">, <코드 클래스 = "값"> 4 <코드 클래스 = "일반">)])

출력:

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

그러나 더 이상 병렬화하지 않는다는 것은 반드시 더 빠른 처리를 의미합니다. 사용 가능한 리소스에 따라 다르며 더 많은 게이트웨이와 채널이 열릴수록 더 많은 오버헤드가 발생합니다. 이상적으로는 리소스 활용을 최대화하기 위해 CPU 코어당 하나의 게이트웨이와 채널이 있어야 합니다. i가 첫 번째 요소인 2개의 튜플을 수신하고 다시 전송하는 한 깨끗한 모듈과 함께 plists.map() 을 사용하십시오. 이 패턴은 최대한 빨리 처리하기 위해 처리해야 하는 숫자가 많을 때 가장 유용합니다.