2011-01-02 2 views
29

왜 표준 샘플 코드의 모든 부분이 필요한지 이해하려고 노력하고 있습니다.하스켈에서 '파'와 'seq'또는 'pseq'가 필요한 이유는 무엇입니까?

a `par` b `pseq` a+b 

다음 코드로 충분하지 않은 이유는 무엇입니까?

a `par` b `par` a+b 

위의 표현식은 매우 설명적인 것처럼 보입니다. ab을 병렬로 평가하고 결과 a+b를 리턴하십시오. 효율성의 이유 일뿐입니다. 두 번째 버전은 한 번에 두 번 대신 두 번 실행됩니다.

다음은 좀 더 간결한 버전은 어떻습니까?

a `par` a+b 

원래 표준 코드에서와 같이 ba+b보다 먼저 평가되는지 확인해야하는 이유는 무엇입니까?

답변

29

확인. 요약 http://community.haskell.org/~simonmar/papers/threadscope.pdf

,

a `par` b `par` a+b 

a `par` a+b 

평가의 순서의 부족이의 문제 : 나는 다음과 같은 용지는 내 질문에 대답을 생각합니다. 두 버전 모두 메인 스레드는 즉시 a (또는 때로는 b)에서 작동하고, 메인 스레드가 이미 평가를 시작했는지 평가하기 위해 스레드를 시작할 필요가 없기 때문에 스파크가 즉시 "어지러 울"게됩니다.

원래 버전

a `par` b `pseq` a+b 

는 메인 스레드가a+b 전에 b에서 작동 (또는 대신 다른 a 평가하기 시작했을 것이다) 따라서에 대한 스레드로 실현하는 스파크 a을위한 기회를 제공, 보장 병렬 평가.

+6

이것은 정확하며이 문제에 대해서는'seq'가 왜 부족한지를 설명합니다. 'seq'는 평가 순서에 대한 보장을하지 않습니다. 'seq b (a + b)'에서'(a + b)'가 평가 될 때'b'가 WHNF에있는 한 주 스레드는'b' 전에'a'를 평가할 수 있습니다. –

+2

필자는 그 인자가'par a (par b (a + b)) '문제를 어떻게 묘사하는지 보지 못합니다. 확실히'a' 또는'b'가 즉시 평가 될 것이고, 해당 불꽃이 휘젓는 것입니다. 다른 스파크는 대단히 살아 있어야 병렬성을 생성 할 수 있습니다. 물론 스파크를 만들어내는 것이 가장 효율적인 방법은 아닐지 모르지만 컴파일러에게 평가 순서 질문을 남깁니다. – gereeter

+0

'par a (a + b)'의 경우 런타임이 대신에'b'를 먼저 선택하면 "행운"병렬 처리가 가능합니다. 그러면 'a'스파크가 울리지 않을 것입니다. 이것은 PDF : community.haskell.org/~simonmar/papers/threadscope.pdf (2 페이지)에 언급되어 있습니다. – CMCDragonkai

16
a `par` b `par` a+b 

네, 병렬로 a와 b를 평가하고 A + B를 반환합니다.

그러나 pseq는 A + B되기 전에 모두 A 및 B 평가 보장한다.

해당 주제에 대한 자세한 내용은 this link을 참조하십시오.

6

a `par` b `par` a+bab 모두 불꽃을 생성하지만 a+b (즉, 그것은 메인 쓰레드로 평가) 이렇게 불꽃 중 하나가 실패하다 즉시 도달한다. 문제는 불필요한 불꽃을 만들었 기 때문에 효율성입니다. 이것을 사용하여 병렬 분할을 구현하는 경우 &가 정복되면 오버 헤드가 속도를 제한하게됩니다.

a `par` a+b은 단 한 번의 스파크 만 생성하기 때문에 더 좋아 보입니다. 그러나 전에 a을 평가하려고 시도하면 a에 대한 스파크가 울리며 b에는 스파크가 없으므로 순차적 평가는 a+b이됩니다. 순서를 b+a으로 바꾸는 것은이 문제를 해결할 것이지만, 코드로서 이것은 순서를 강제하지 않으며 하스켈은 이것을 a+b으로 여전히 평가할 수 있습니다.

따라서 우리는 a+b을 평가하기 전에 a `par` b `pseq` a+b을 주 스레드에서 b의 평가를 수행합니다. 이렇게하면 a+b을 평가하기 전에 구체화 할 수있는 불꽃이 a 발생하며 불필요한 불꽃을 생성하지 않았습니다.

관련 문제