2013-02-04 26 views
13

Tôi đang làm việc với mclapply từ gói multicore (trên Ubuntu) và tôi đang viết một chức năng yêu cầu kết quả của mclapply(x, f) được trả lại theo thứ tự (tức là, f(x[1]), f(x[2]), ...., f(x[n])).Được bảo đảm chắc chắn sẽ trả lại kết quả theo thứ tự?

# multicore doesn't work on Windows 

require(multicore) 
unlist(mclapply(
    1:10, 
    function(x){ 
     Sys.sleep(sample(1:5, size = 1)) 
     identity(x)}, mc.cores = 2)) 

[1] 1 2 3 4 5 6 7 8 9 10 

Đoạn mã trên dường như ngụ ý rằng mclapply trả về kết quả theo thứ tự giống như lapply. Tuy nhiên, nếu giả định này là sai, tôi sẽ phải dành một thời gian dài refactoring mã của tôi, vì vậy tôi hy vọng để có được sự đảm bảo từ một ai đó quen thuộc hơn với gói này/song song tính toán giả định này là chính xác.

Có an toàn để giả định rằng mclapply luôn trả về kết quả theo thứ tự, bất kể các đối số tùy chọn được đưa ra?

+1

Các tài liệu không chỉ ra rằng kết quả có thể đến trong scrambled, và nó là rõ ràng rằng đây là một song song phiên bản 'lapply', trả về danh sách được sắp xếp làm đầu vào. Bạn có thể chạy một phần mã của bạn ở chế độ tuần tự và song song và xem điều này có phù hợp với trường hợp cụ thể của bạn hay không. Tôi sẽ mạo hiểm một dự đoán rằng nó. –

Trả lời

15

Câu trả lời ngắn: nó trả về kết quả theo đúng thứ tự.

Nhưng tất nhiên, bạn nên đọc mã chính mình (mclapply là một chức năng R ...)

Các trang người đàn ông cho collect đưa ra một số gợi ý hơn:

Lưu ý: Nếu expr sử dụng thấp các chức năng đa lõi như sendMaster một công việc đơn lẻ có thể cung cấp kết quả nhiều lần và người dùng có trách nhiệm giải thích chúng một cách chính xác.

Tuy nhiên, nếu bạn không gây rối với cấp thấp,

thu tờ bất kỳ kết quả mà có sẵn trong danh sách. Kết quả sẽ có cùng thứ tự như các công việc được chỉ định. Nếu có nhiều công việc và một công việc có tên, nó sẽ được sử dụng để đặt tên cho kết quả, nếu không thì ID tiến trình của nó sẽ được sử dụng.

(tôi nhấn mạnh)

Bây giờ cho mclapply. Một glanc nhanh chóng so với sản lượng mã nguồn:

  • nếu !mc.preschedule và không có thêm việc làm hơn so với lõi (length (X) <= cores) parallelcollect được sử dụng, xem ở trên.
  • nếu mc.preschedule hoặc nhiều công việc hơn lõi, mclapply sẽ tự xử lý đơn hàng - xem mã.

Tuy nhiên, đây là một phiên bản sửa đổi một chút thử nghiệm của mình:

> unlist (mclapply(1:10, function(x){ 
    Sys.sleep(sample(1:5, size = 1)); 
    cat (x, " ");  
    identity(x)}, 
    mc.cores = 2, mc.preschedule = FALSE)) 
1 2 4 3 6 5 7 8 9 10 [1] 1 2 3 4 5 6 7 8 9 10 
> unlist (mclapply(1:10, function(x){ 
    Sys.sleep(sample(1:5, size = 1)); 
    cat (x, " ");  
    identity(x)}, 
    mc.cores = 2, mc.preschedule = TRUE)) 
1 3 2 5 4 6 7 8 10 9 [1] 1 2 3 4 5 6 7 8 9 10 

nào cho thấy các kết quả được trả về theo thứ tự khác nhau bằng các công việc con (chính xác hơn: Việc làm đứa trẻ đang sắp sửa hoàn thành vào khác nhau thứ tự), nhưng kết quả được lắp ráp theo thứ tự ban đầu.

(hoạt động trên giao diện điều khiển, nhưng không phải trong RStudio - các cat s không hiển thị ở đó)