2010-12-18 4 views
1

사무실에서 사용한 컴퓨터는 최근 쿼드 코어로 업그레이드되었습니다. 가끔은 R을 사용하여 명시 적 루프를 수행해야하므로 가끔 축복입니다. 결과는 하나의 논리적 인 규칙에 기반을두고 있는데, 나는 명시적인 루프가 아닌 다른 방법을 찾아 낼 방법이 없다.doSNOW를 사용하여 명시적인 루프 속도 향상 R

몇 가지 배경 정보를 보려면 때때로 약 10000-20000 행이 필요합니다.이 행은 2 열을보고 값과 일부 논리 규칙을 기반으로 새 열의 값을 생성해야합니다.

내가 더 잘 사용되지 않는 CPU 파워를 활용하기 위해 doSNOW 패키지를 사용하는 것을 시도하고있다

, 나는 here에서의 예에 따라 아래와 같이 데모 스크립트를 작성했습니다 : 나는 원자와 넷북을 사용하고

library(doSNOW) 
# rm(list=ls()) 

cl<-makeCluster(2) # I have two cores 
registerDoSNOW(cl) 

table <- data.frame(a=rnorm(1000),b=rnorm(1000)) 

process <- function(table) 
       {for (loop in (1:nrow(table))) 
        {table[loop,"c"] <- with(table[loop,], a*b) 
        assign("table",table,envir=.GlobalEnv) 
        } 
       } 


system.time(process(table)) 

system.time(foreach(j=1:2) %dopar% process(table)) 

stopCluster(cl) 

내부 CPU이 밖으로 시도하지만 결과는 이상한 : doSNOW 사용 후

system.time(process(table)) 
user system elapsed 
2.336 0.028 2.308 

system.time(foreach(j=1:2) %dopar% process(table)) 
user system elapsed 
0.160 0.032 3.646 

, 결과에 필요한 시간, 나는이 내 ATOM 넷북의 문제가 궁금하거나 한 더 오래 doSNOW를 사용하지 않고보다 나는 무엇이든 잘못 만든다. 코드?

감사합니다.

+0

질문에 답변하지는 않지만 병렬 백엔드 (예 : MPI)를 사용하고 계신가요? – Shane

+6

코드를 살펴 봤습니다. ** 많은 사람들을 정말로 불행하게하지 않으려면 ** 여기에있는 코드 샘플에'rm (list = ls())'를 넣지 마십시오. – Shane

+1

이 기능이 최적화하려고하는 실제 기능입니까? 그렇다면 벡터화 된 방식으로 작성하는 것이 훨씬 낫습니다. 팁 : 나는 당신이 무언가를 잘못하고있는 가능성을 배정하는 데 사용하고 있습니다. – hadley

답변

2

우선, 하나의 컴퓨터에서 눈보다 멀티 코어를 사용하는 것이 좋습니다. 그것은 파이프 대신 소켓을 사용할 수 있다는 사실을 이용합니다. 또한 포크에 필요한 시간은 새 프로세스를 초기화하는 것보다 작습니다.

이제는 평행 버전이 넷북에서 더 오래 작동하는 이유입니다. 병렬 평가로 전환하는 필연적 인 시간 비용이 있으며 여러 스레드에서 이득을 지배 할 수 있습니다. 더 긴 직업의 경우,이 시간은 무시해도 좋을 것이고 당신은 더 빨리 할 수 ​​있습니다.

+0

멀티 코어를 사용하고 싶지만'doMC' 패키지를 사용할 수없는 WinXP 시스템을 사용하고 있습니다. – lokheart

+1

Windows에서 doSMP를 사용할 수 있습니다. – Shane

6

내가 알 수있는 한, 예제에서는 snow없이 한 번만 실행하고 snow으로 두 번 실행합니다. 특히 foreach 인프라를 추가 할 때 프로세스를 병렬로 실행하면 추가되는 오버 헤드가 있습니다. 따라서 실행 당 평균 시간은 순차적으로 실행 한 경우보다 적지 만 작업을 분할 할 때 전체적으로 동일한 시간을 기대할 수는 없습니다.

"결과가 doSNOW를 사용하지 않은 경우보다 길다"라는 말은 잘못되었습니다. 사실, 만약 당신이 첫 번째 것을 두 번 실행한다면, 그것은 거의 두 배가 걸릴 것입니다. 따라서 snow은 실제로 성능을 향상 시켰습니다. 그것의

system.time(for(i in 1:2) process(table)) 
system.time(foreach(j=1:2) %dopar% process(table)) 

생각해이 방법 :

이 공정한 비교 당신이 각각 독립적으로 1 분 작업을 할 수있는 두 사람이 있다고 가정합니다. 한 사람이 여러 작업을 수행하는 경우 추가 오버 헤드가 있다고 가정 해 봅시다. 그러나 당신이 그들에게 독립적으로 일할 것을 요청하면 결과를 함께 모으는 데 시간이 조금 걸립니다. 한 사람에게 두 가지 일을하도록 요청하면 2 분이 걸릴 것입니다. 각 사람에게 개별적으로 작업하도록 요청하면 결국 의사 소통이 필요하기 때문에 총 1 분 이상 걸립니다.

0

속도가 느려지는 이유 중 하나는 최신 듀얼 코어 Atom이없는 한 단일 코어 CPU를 사용하고있을 가능성이 높기 때문일 수 있습니다. 이 경우 foreach() 함수없이 R을 순차적으로 실행하지만 프로세스에서 병렬로 실행하려고하는 오버 헤드가 추가됩니다. 제 제안은 사무실에서 일어난 일을보기 위해 시도하는 것입니다.

+0

거기에 멀티 스레드로 만들 가능성이 없습니까? – toxicate20