2013-03-04 14 views
6

Tôi đang gặp phải một hành vi lạ trong máy tính của mình khi phân phối các quy trình giữa các lõi của nó bằng cách sử dụng doMC và foreach. Có ai biết tại sao sử dụng lõi đơn tôi có hiệu suất tốt hơn so với sử dụng 2 lõi? Như bạn có thể thấy, xử lý cùng một mã mà không cần đăng ký bất kỳ lõi nào (được cho là chỉ sử dụng 1 lõi) để xử lý hiệu quả thời gian hơn nhiều. Trong khi% do% có vẻ hoạt động tốt hơn% dopar%, hãy đăng ký 2 lõi trong số 4 sản lượng để tốn nhiều thời gian hơn.Song song trong R:% dopar% so với% do%. Tại sao sử dụng một lõi đơn mang lại hiệu suất tốt hơn?

require(foreach) 
require(doMC) 
# 1-core 
> system.time(m <- foreach(i=1:100) %dopar% 
+ matrix(rnorm(1000*1000), ncol=5000)) 
    user system elapsed 
    9.285 1.895 11.083 
> system.time(m <- foreach(i=1:100) %do% 
+ matrix(rnorm(1000*1000), ncol=5000)) 
    user system elapsed 
    9.139 1.879 10.979 

# 2-core 
> registerDoMC(cores=2) 
> system.time(m <- foreach(i=1:100) %dopar% 
+ matrix(rnorm(1000*1000), ncol=5000)) 
    user system elapsed 
    3.322 3.737 132.027 
> system.time(m <- foreach(i=1:100) %do% 
+ matrix(rnorm(1000*1000), ncol=5000)) 
    user system elapsed 
    9.744 2.054 11.740 

Sử dụng 4 lõi trong vài thử nghiệm mang lại kết quả đến rất khác nhau:

> registerDoMC(cores=4) 
> system.time(m <- foreach(i=1:100) %dopar% 
{ matrix(rnorm(1000*1000), ncol=5000) }) 
    user system elapsed 
11.522 4.082 24.444 
> system.time(m <- foreach(i=1:100) %dopar% 
{ matrix(rnorm(1000*1000), ncol=5000) }) 
    user system elapsed 
21.388 6.299 25.437 
> system.time(m <- foreach(i=1:100) %dopar% 
{ matrix(rnorm(1000*1000), ncol=5000) }) 
    user system elapsed 
17.439 5.250 9.300 
> system.time(m <- foreach(i=1:100) %dopar% 
{ matrix(rnorm(1000*1000), ncol=5000) }) 
    user system elapsed 
17.480 5.264 9.170 
+1

1. Sản xuất một ma trận đơn không phải là (nói chung) được thực hiện song song trừ khi bạn xác định cách thực hiện và bạn chưa thực hiện. Bạn nên mong đợi kết quả tồi tệ hơn khi sử dụng nhiều hơn một lõi. 2. 'RegisterDoMC' có ảnh hưởng đến'% do% 'không? Kết quả tương tự. –

+0

@MatthewLundberg: Vui lòng '% do%' kiểm tra tài liệu :-) – krlmlr

+0

Trừ khi tôi đọc sai kết quả đầu ra, tôi không thấy _ "xử lý hiệu quả thời gian nhiều hơn" _, có vẻ như sự khác biệt không đáng kể chỉ là 1,5% –

Trả lời

8

Đó là sự kết hợp của kết quả mà ăn tất cả các thời gian xử lý. Đây là thời gian trên máy của tôi cho trường hợp cores=2 nếu không có kết quả nào được trả về. Về cơ bản nó giống như mã, chỉ các ma trận được tạo mới bị loại bỏ thay vì được trả lại:

> system.time(m <- foreach(i=1:100) %do% 
+ { matrix(rnorm(1000*1000), ncol=5000); NULL }) 
    user system elapsed 
13.793 0.376 14.197 
> system.time(m <- foreach(i=1:100) %dopar% 
+ { matrix(rnorm(1000*1000), ncol=5000); NULL }) 
    user system elapsed 
    8.057 5.236 9.970 

Vẫn chưa tối ưu, nhưng ít nhất là phiên bản song song giờ đây nhanh hơn.

Đây là từ tài liệu của doMC:

Gói doMC cung cấp một backend song song cho foreach/%dopar% chức năng sử dụng các chức năng đa lõi của gói parallel.

Hiện tại, parallel sử dụng cơ chế fork để tạo ra các bản sao giống hệt nhau của quy trình R. Thu thập kết quả từ các quá trình riêng biệt là một nhiệm vụ tốn kém, và đây là những gì bạn thấy trong các phép đo thời gian của bạn.

+1

Vâng, bạn có điểm. Mã của tôi đã sai do không phân phối các quy trình. Bây giờ, hành vi như tôi mong đợi. Cảm ơn vì đã chỉ ra sai lầm của tôi. – daniel

+1

@ user792000: Erm, no. Các quy trình cũng được phân phối trong mã của bạn. Sự khác biệt duy nhất là mã của bạn * trả về * ma trận nó tạo ra, mã của tôi loại bỏ chúng. – krlmlr

+0

Nó thực sự là lạ. Sử dụng 4 lõi trong vài thử nghiệm mang lại kết quả rất khác nhau: – daniel