2012-03-21 29 views
6

Xin chào, tôi đang cố gắng sử dụng ddply trong thư viện plyr trong R, với gói MC. Nó dường như không tăng tốc độ tính toán. Đây là mã tôi chạy:đa lõi với plyr, MC

require(doMC) 
registerDoMC(4) 
getDoParWorkers() 
##> 4 
test <- data.frame(x=1:10000, y=rep(c(1:20), 500)) 
system.time(ddply(test, "y", mean)) 
    # user system elapsed 
    # 0.015 0.000 0.015 
system.time(ddply(test, "y", mean, .parallel=TRUE)) 
    # user system elapsed 
    # 223.062 2.825 1.093 

Bất kỳ ý tưởng nào?

+3

Tùy thuộc vào các phép tính thực tế bạn đang thực hiện, gói 'data.table' thực sự có thể tăng tốc chúng. Đối với tất cả các đặc tính của nó, việc thực thi 'split-apply-combined' trong gói 'plyr' thực sự khá chậm, trong khi' data.table' là thiết bị đầu tiên và được thiết kế trước hết cho tốc độ. (Nếu bạn bị hấp dẫn, chỉ cần tìm kiếm SO cho một cái gì đó như '[r] [data.table] plyr' để có được rất nhiều điểm khởi đầu có thể). –

+0

Cảm ơn bạn Josh, tôi sẽ xem xét. – Alex

Trả lời

10

Chức năng mean hoạt động quá nhanh so với chi phí truyền thông cần thiết để phân phối các phần chia tách cho mỗi lõi và truy xuất kết quả.

Đây là sự cố "phổ biến" mà mọi người gặp phải với tính toán phân tán. Họ hy vọng nó sẽ làm cho mọi thứ chạy nhanh hơn bởi vì họ quên có chi phí (giao tiếp giữa các nút) cũng như các lợi ích (sử dụng nhiều lõi).

Điều gì đó cụ thể để xử lý song song trong plyr: chỉ có chức năng được chạy trên nhiều lõi. Việc chia tách và kết hợp vẫn được thực hiện trên một lõi đơn, do đó hàm bạn đang áp dụng sẽ phải rất tốn kém tính toán để xem lợi ích khi sử dụng các hàm plyr song song.

+0

Đây chỉ là một ví dụ. Khung dữ liệu thực tế tôi có là 4 triệu hàng với 2000 nhóm. Mã song song và không trả về cùng một lúc. – Alex

+1

@Alex: Nếu data.frame của bạn là rất lớn, thì chức năng của bạn sẽ cần phải được tính toán nhiều hơn vì phần lớn thời gian dành cho 'ddply' sẽ tách và kết hợp, không áp dụng hàm. –

+0

tôi thấy .. vì vậy phần nó phân phối là ứng dụng thực tế của hàm .. việc tách nó vẫn làm trên 1 lõi? – Alex

1

Tiếp tục câu trả lời của Joshua, có sự khắc phục nếu bạn muốn tăng tốc hoạt động này. Nó được lấy cảm hứng từ hệ tư tưởng Map-reduce và tôi đã thực hiện một POC trên một tập dữ liệu mẫu trong khi quay trở lại.

Tôi đã sử dụng thư viện tuyết rơi- Tôi tin rằng bạn cũng có thể làm việc với doMC.

# On my phone, please pardon typos/bugs 

test <- data.frame(x=1:1000000, y=rep(c(1:20), 500)) 

testList = list() 
testList[[1]] <- test[c(1:250000),] 
testList[[2]] <- test[c(250001:500000),] 
testList[[3]] <- test[c(500001:750000),] 
testList[[4]] <- test[c(750001:1000000),] 

# Write a function for the above - Need to find optimum number of splits 

sfInit(parallel = TRUE, cpus=4) 
sfCluster(plyr) 
meanList = sfClusterSpplyLB(testList, function(x) ddply(test, "y", mean)) 

sfStop() 

aggregate(meanList, by=list(y), FUN=mean) 

này sức giúp bạn, cho rằng chúng ta đang làm thường xuyên chia kết hợp một cách phân tán. Điều này làm việc cho các phương tiện khi kích thước của các phân chia là như nhau, nó hoạt động cho tổng, min/max, đếm vv là OK nhưng có một số hoạt động mà chúng tôi không thể sử dụng này cho.

Các vấn đề liên quan