2013-09-26 5 views
0

는 일반적으로 우리는 하나에 의해 배열을 반복 :동시 레일 반복/작업

a = [1, 2, 3, 4] 
b = [] 

a.each do |x| 
    b << x * 5 
end 

b = [5, 10, 15, 20] 

내가 배열의 내용의 순서에 대해 관심이 있지만, 반복의 속도를 증가하지 않으려면 곱셈 연산을 동시에 실행함으로써? 예를 들어 다음과 같은 결과가 허용됩니다.

b = [15, 10, 5, 20] # or 
b = [5, 20, 15, 10] # or 
b = [20, 15, 5, 10] 

어떻게하면됩니까?

+0

진정한 병렬 처리가 없습니다. 더 나은 루비 (Rubinius or JRuby)를 사용하고 있지 않는 한 –

+1

동시 처리를 시뮬레이트하는 [parallel] (https://github.com/grosser/parallel)라고 불리는 매우 멋진 보석이 있습니다 만, 현재 GIL을 피할 수는 없습니다 YARV 또는 MRI 구현. –

답변

4

MRI는 GIL 때문에 진정한 멀티 코어 병렬 처리를 수행하지 않습니다. 스레딩은 실제로 CPU 바운드 작업에 대한 성능 향상을 가져 오지 않습니다 (IO 바인딩 작업에서 확실히 수행함). 실제로 여러 코어에 작업을 동시에 분배 할 수 있기 때문에 CPU 바인딩 작업에 대한 병렬 처리를 위해 JRuby 또는 Rubinius를 실행해야합니다.

당신이 진정한 병렬 제공하는 VM 실행하는 가정 말했다 :.

b = a.map {|x| 
    Thread.new { 
    Thread.current[:out] = x * 5 
    } 
}.map {|t| t.join; t[:out] } 

(이 코드는 아주 못생긴 실제 사용을 위해 리팩토링되어야한다 또한 스레드 순서로 결과를 반환합니다 이 태스크를 병렬 처리하는 동안 생성되었습니다.)

여기서 중요한 점은 1) 스레드 로컬 변수에서 반환 값 전파 (따라서 possibly-unatomic operation을 공유 값으로 수행 할 필요가 없으므로 원하는 경우 2) 각각의 쓰레드에 #join을 호출하면, 당신은 뮤텍스를 도입 할 필요가있다. o 생성 된 각 스레드가 실행을 완료했음을 확신합니다.