1

나는 다음과 같은 프리젠 테이션을 읽고 있었다 :지도 함수가 본질적으로 평행 한 이유는 무엇입니까?

http://www.idt.mdh.se/kurser/DVA201/slides/parallel-4up.pdf

및 저자가지도 기능은 병렬 아주 잘 구축되어 있음을 주장한다 (특히 그는 3 페이지 또는 슬라이드 9와 10에 대한 자신의 주장을 뒷받침).

목록의 각 값을 +1만큼 증가시키는 문제가 발생하면 목록을 반복적으로 사용하면 인덱스 값이 변경되어 잠재적 인 경쟁 조건 문제가 발생하는 것을 볼 수 있습니다. 하지만 맵 기능으로 프로그래머가 병렬로 코드를 작성하는 것이 더 좋은지 궁금합니다.

지도가 재귀 적으로 정의 되었기 때문입니까? 그래서 각 함수 호출을 다른 스레드에 던질 수 있습니까?

누군가가 몇 가지 구체적인 정보를 제공하기를 바랍니다. 감사합니다.

+0

을하기 때문에에 f' 기능 '의 각 응용 프로그램 입력 목록의 요소는 다른 응용 프로그램에서 다른 요소로 * 독립적 *이므로 서로 모두 독립적으로, 즉 병렬로 수행 할 수 있습니다. 가상의'par_map'은 저장소를 할당하여 결과 목록을 백업하고, 목록의 각 요소'e'에 대한 새로운 스레드의 실행을 촉구하며,'e' 결과로 갱신 될 필요가있는 장소에 대한 참조를 제공합니다. fe'. 더 이상의 활성 스레드가 없으면'map'이 끝났습니다. 물론 각 스레드가 1000 'e's 블록을 만들 수 있습니다. –

답변

3

map 함수는 동일한 순수 함수를 컬렉션의 n 요소에 적용하고 결과를 집계합니다. 정의에 따라 함수의 반환 값은 입력에 전적으로 의존하므로 컬렉션의 멤버에게 함수를 적용하는 순서는 중요하지 않습니다.

+0

맞 겠지만 목록을 다른 청크로 분할하고 반복적으로 자체 스레드의 각 청크를 루프로 처리 할 수 ​​있습니까? 그게 위의 것과 어떻게 다릅니 까? –

+0

아마 아무 기능적으로 ... 나는 그것이 복잡성의 문제라고 생각해. 설명하는 알고리즘은 더 복잡 할 수 있지만 라이브러리를 사용하여 병렬 맵을 수행 할 수는 있습니다. 적어도 그것이 그의 요점을 해석하는 방법입니다. –

+0

나는지도의 내부에 더 관심이 있다고 가정한다. 만약 map이 재귀 적으로 정의된다면 map (f (x), list) = list가 비어 있다면 empty list를 리턴하고 f (head_of_list)를 map (f (x), list.tail)과 함께 concat으로 반환한다. . 만약 map이 재귀 적으로 정의된다면, map은 순차적으로 f (head_of_list)를 순차적으로 계산하는 것을 피할 수 있습니까? (루프처럼) –

3

다른 사람들은 이미 표준 map 구현이 병렬 적이 지 않다는 것을 설명했습니다. 당신이 그것을 태그 있기 때문에, 당신은 scala.collection.parallel 패키지도 ParIterable 및 기타 유형의 Parallel Collections Overview 및 설명서를 참조하십시오 단순히

val list = ... // some list 
list.par.map(x => ...) // instead of list.map(x => ...) 

로 병렬 버전을 얻을 수 있습니다

하지만 스칼라에서

.

평행선의 구현은 https://github.com/scala/scala/blob/v2.12.1/src/library/scala/collection/parallel/ParIterableLike.scala에서 찾을 수 있습니다 (def mapclass Map 찾아보기). 매우 간단한 인프라가 필요하며 반드시 순차적 인 map의 재귀 적 정의를 취하여 병렬화하는 것이 아닙니다.

루프를 통해지도를 정의했다면 어떻게 고장 났을까요?

슬라이드는 말에 예를 들어 F # 병렬 배열을 제공하고 https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/array.fs#L266에서 당신은 루프가 아닌 병렬 구현을 볼 수 있습니다

let inline map (mapping: 'T -> 'U) (array:'T[]) = 
    checkNonNull "array" array    
    let res : 'U[] = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked array.Length 
    for i = 0 to res.Length-1 do 
     res.[i] <- mapping array.[i] 
    res 
+0

감사합니다. Alexey. 사용하기 쉬운 병렬성을 만드는 데 필수적인 순차적이지만지도의 표준 재귀 정의를 호출하겠습니까? 루프를 통해지도를 정의했다면 어떻게 고장 났을까요? (나는이 질문들에 대한 답이 하나의 코멘트보다 클 것이라고 생각하지만 어떤 고차원의 개관은 굉장히 좋습니다!) –

+0

아니요, 필수적이거나 특별히 관련이 없습니다. 슬라이드는 재귀 구현에 대해 전혀 말하지 않고 있으며,'map'의 명세에 대해서만 병렬로 구현할 수 있습니다. –

+0

두 번째 질문에 대한 답은 편집을 참조하십시오. –

관련 문제