2012-02-21 4 views
2

일부 코드를 테스트하고 있습니다 (더 빠르게하려고하지만 차이점을 이해하려고 시도하고 있습니다). 메모리에 테이블을 만드는 루프가 있습니다. 그런 다음 다중 프로세스를 시도했지만 다중 프로세스에서 메모리 사용량이 이상하게 보입니다. 테이블을 자체적으로 실행하면 시스템의 모든 메모리가 필요할 때까지 테이블이 계속 커지고 성장하지만 멀티 프로세싱을 사용하면 전체 시간이 낮게 유지되어 어떤 일을하는지 궁금해집니다. 다중 처리되지 않은 코드를 빠르게 재 작성하려고합니다. 여기 다중 처리에서 공유 항목에 메모리 제한이 있습니까?

은 (단지/추가는 시스템 프로세스를 볼 빠르거나 느린 실행하기 위해 데이터 변수에서 항목을 제거 Multiprocessed 상단에 있고 nonmulti 하단에 있습니다.) 일부 코드입니다 :

from multiprocessing import Pool 
from multiprocessing.managers import BaseManager, DictProxy 
from collections import defaultdict 

class MyManager(BaseManager): 
    pass 

MyManager.register('defaultdict', defaultdict, DictProxy) 

def test(i,x, T): 
    target_sum = 1000 
    # T[x, i] is True if 'x' can be solved 
    # by a linear combination of data[:i+1] 
    #T = defaultdict(bool)   # all values are False by default 
    T[0, 0] = True    # base case 

    for s in range(target_sum + 1): #set the range of one higher than sum to include sum itself 
      #print s 
      for c in range(s/x + 1): 
       if T[s - c * x, i]: 
        T[s, i + 1] = True 


data = [2,5,8,10,12,50]     
pool = Pool(processes=2) 
mgr = MyManager() 
mgr.start() 
T = mgr.defaultdict(bool) 
T[0, 0] = True 
for i, x in enumerate(data): # i is index, x is data[i] 
    pool.apply_async(test, (i,x, T)) 
pool.close() 
pool.join() 
pool.terminate() 


print 'size of Table(with multiprocesing) is:', len(T) 
count_of_true = [] 
for x in T.items(): 
    if T[x] == True: 
     count_of_true.append(x) 
print 'total number of true(with multiprocesing) is ', len(count_of_true) 


#now lets try without multiprocessing 
target_sum = 100 
# T[x, i] is True if 'x' can be solved 
# by a linear combination of data[:i+1] 
T1 = defaultdict(bool)   # all values are False by default 
T1[0, 0] = True    # base case 


for i, x in enumerate(data): # i is index, x is data[i] 
    for s in range(target_sum + 1): #set the range of one higher than sum to include sum itself 
      for c in range(s/x + 1): 
       if T1[s - c * x, i]: 
        T1[s, i + 1] = True 

print 'size of Table(without multiprocesing) is ', len(T1) 

count = [] 
for x in T1: 
    if T1[x] == True: 
     count.append(x) 

print 'total number of true(without multiprocessing) is ', len(count) 

실험으로 두 코드를 두 파일에 넣고 나란히 실행했습니다. 두 개의 멀티는 약 20 %를 차지하며 각각 0.5 %의 메모리 만 사용합니다. 단일 프로세스 (멀티 없음)는 코어의 75 %와 최대 50 %의 메모리 사용량을 사용합니다.

+0

당신은 다음과 같이 씁니다 : "스스로 실행하면 ..."Pool (프로세스 = 1)을 설정하는 것에 대해 이야기합니까? – itsafire

+0

정확하지 않습니다. 위의 코드에서 하나는 다중 프로세스 풀에 래핑되고 다른 하나는 풀없이 실행됩니다. – Lostsoul

답변

2

내가 당신의 코드를 올바르게 이해했다면, 실제 문제는 멀티 프로세싱으로 룩업 테이블을 구축 할 수 없다는 것입니다.

이 :

for i, x in enumerate(data): 
    for s in range(target_sum + 1): 
     for c in range(s/x + 1): 
      if T1[s - c * x, i]: 
       T1[s, i + 1] = True 

작품은 다른 후 itone 단계를 수행하고 있기 때문이다. 당신이 RecursivelyListAllThatWork() 같이 새로운 것들을 구축하기 위해 이전 결과를 필요 beacuse

def test(i,x, T): 
    target_sum = 1000 
    T[0, 0] = True 
    for s in range(target_sum + 1): 
     for c in range(s/x + 1): 
      if T[s - c * x, i]: 
       T[s, i + 1] = True 

# [...] 

for i, x in enumerate(data): 
    pool.apply_async(test, (i,x, T)) 

이 같은 일을하지 않음 :이 있지만

.

for x in T: 
    if T[x] == True: 
     count_of_true.append(x) 

을 그리고 심지어 경우에 당신이 돈에 불구하고, ==하지 isTrue을 비교하는 것이 좋습니다 :

for x in T.items(): 
    if T[x] == True: 
     count_of_true.append(x) 

은 다음과 같아야합니다

이, 또한 계산에 버그가있다 그 중 하나가 필요하지 않습니다 :

for x in T: 
    if T[x]: 
     count_of_true.append(x) 

참고로, Iothers이 이미 말했기 때문에 실제로 여기에 defaultdict이 필요하지 않습니다.

+0

하지만 프로세스 = 1 인 경우에도 멀티 프로세싱 없이는 메모리를 최대한 활용하지 못합니다. 나는 내가 만든 다른 다중 프로세스 (작업이 커짐에 따라 다중이 단일 지점을 지나서 성장하지 않는 것처럼 보이지만 단일 프로세스는 메모리를 급상승)로 같은 것을 느낀다. – Lostsoul

+0

@Lostsoul : 나는 그렇게 생각하지 않는다. 문제는 for-loop로 모든 테이블을 반복적으로 수행한다는 것입니다. 코드를 실행했는데 멀티 프로세싱 테이블이없는 것보다 거의 10 배 더 큽니다. 여러 개의 공유 테이블 대신 하나의 공유 테이블을 사용 중이었기 때문에 메모리 사용량에 대해 설명했으나 여기서는 제시되지 않았습니다. –

+0

그러나 다중 처리가 여전히 다중이 아닌 하나의 공유 테이블을 갖지 않거나 자체 버전의 테이블에서 작업하고 마스터 또는 다른 것과 동기화하는 중입니까? 죄송 합니다만 나는 아직도 메모리 차이를 이해하지 못합니다.또한, 나는 당신의 업데이트 된 답변을 읽어 주셔서 감사합니다. – Lostsoul

관련 문제