2016-12-17 2 views
0

하스켈 초보자에게 병렬 처리를 효과적으로 작동시키는 것에 관한 질문.Haskell/GHC에서의 평행 병렬 처리

Advent of Code Day 14의 과제는 특정 속성을 충족시키는 해시를 제공하는 처음 n 개의 정수를 찾고 정수 시퀀스의 MD5 해시를 만드는 것입니다. 나는 본질적으로 해시를 생성 한 다음 필터링함으로써이를 수행합니다.

저는 여러 개의 코어를 사용하여 해시를 생성하는 병렬 처리를 시도하는 것이 좋을 것이라고 생각했습니다.

md5sequenceS :: [String] 
md5sequenceS = [makeMd5 i | i <- [0..]] 
    where makeMd5 i = stretch $ getHash (salt ++ show i) 
      stretch h0 = foldr (\_ h -> getHash h) h0 [1..2016] 

을 ... 그리고 그것은 약 4 분 안에 답을주고, 천천히이기는하지만, 잘 작동 :

해시 창조의 비 병렬 버전은 다음과 같습니다.

병렬 버전은 다음과 같습니다

md5sequenceS :: [String] 
md5sequenceS = parMap rdeepseq (makeMd5) [0..] 
    where makeMd5 i = stretch $ getHash (salt ++ show i) 
      stretch h0 = foldr (\_ h -> getHash h) h0 [1..2016] 

... 전에 떨어져 parMap rdeepseq 비트에서와 동일합니다. 이것은 잘 작동하지 않습니다. 그것은 내 컴퓨터에서 사용 가능한 메모리를 모두 소비하지만 30 분의 벽 시간이 지나도 응답을 생성하지 못합니다. 그러나 모든 프로세서를 완전히 사용합니다.

통제되지 않은 병렬 처리를 길들이려면 어떻게해야합니까?

는 (문제의 사양은 내가 생성 할 필요가 얼마나 많은 해시에 대한 단서를 제공하지 않지만, 내가 약 30,000 정수 해시 필요가 밝혀졌습니다.)

편집을 허용 대답을 포함

md5sequenceS = withStrategy (parBuffer 100 rdeepseq) $ map (makeMd5) [0..] 
    where makeMd5 i = stretch $ getHash (salt ++ show i) 
      stretch h0 = foldr (\_ h -> getHash h) h0 [1..2016] 

성능은 단일 스레드 버전에 비해 크지 않다 같이 parBuffer 전략을 사용할 수 있습니다,하지만 ...

을 다른 질문

답변

3

parMap 귀하의 경우 무한합니다 모든 목록의 평가를 강제합니다. 대신에 parBuffer과 같은 다른 전략을 사용하면 무한한 목록을 처리 할 수 ​​있습니다.

+1

설명해 주시면 감사하겠습니다. 병렬 버전을 으로 다시 쓰자. 'md5sequenceS = withStrategy (parBuffer 100 rdeepseq) $ map (makeMd5) [0 ..]'이 트릭을 수행한다. 월간 시간은 12 분 코어에서 3 분 44 초이고, 단일 프로세스 버전에서는 5 분 55 초이지만 다른 문제입니다 ... –