2012-03-13 31 views
8

Danh sách, mảng hoặc seq nào hiệu quả hơn để xử lý song song và có thể dễ dàng thực hiện các hoạt động song song như parmap, parfilter, v.v ...?Bộ sưu tập dữ liệu song song trong F #

CHỈNH SỬA: Cảm ơn bạn đã đề xuất. Array.Parallel trông giống như một lựa chọn tốt. Ngoài ra kiểm tra ra PSeq.fs và tôi đã có một câu hỏi về cách làm việc pmap dưới đây.

let pmap f xs = 
    seq { for x in xs -> async { return f xs } } 
    |> Async.Parallel 
    |> Async.RunSynchronously 

Chủ đề mới có được sinh ra cho mỗi phần tử trong chuỗi không? Nếu vậy, có cách nào để phá vỡ các seq thành các khối và tạo ra một nhiệm vụ mới cho mỗi đoạn để có được đánh giá song song?

Tôi cũng muốn xem liệu có bất kỳ triển khai pmap tương tự nào cho danh sách hay không. Tôi thấy Tomas có triển khai ParallelList trong bài đăng trên blog của mình here. Nhưng tôi không chắc liệu chuyển đổi một danh sách thành mảng để thực hiện đánh giá song song không phải chịu quá nhiều chi phí và nếu nó có thể tránh được?

EDIT: Cảm ơn tất cả các yếu tố đầu vào của bạn. Tomas trả lời câu hỏi ban đầu của tôi.

Trả lời câu hỏi của riêng tôi trong chỉnh sửa đầu tiên:

tôi đã cố gắng phá vỡ một danh sách lớn thành những phần sau đó áp dụng async cho mỗi sublist.

let pmapchunk f xs = 
    let chunks = chunk chunksize xs 
    seq { for chunk in chunks -> async { return (Seq.map f) chunk } } 
    |> Async.Parallel 
    |> Async.RunSynchronously 
    |> Seq.concat 

Kết quả: map: 15s, pmap: 7s, pmapchunk: 10s.

+1

Nó phụ thuộc nhưng bạn gần như chắc chắn muốn 'Array.Parallel' và không phải là 'async'. –

Trả lời

9

Có một thực hiện song song của một số mảng hoạt động trong # thư viện F. Nói chung, làm việc với các mảng có lẽ sẽ hiệu quả nhất nếu các hoạt động riêng lẻ mất một thời gian dài.

  • Hãy xem mô-đun Array.Parallel. Nó chứa các hàm để tạo mảng (init), để thực hiện các phép tính với các phần tử (map) và cũng có thể sử dụng chức năng choose để thực hiện lọc.

Nếu bạn đang viết một đường dẫn phức tạp của các thao tác khá đơn giản, nhưng có một số lượng lớn, bạn cần sử dụng PLINQ, song song với toàn bộ đường ống thay vì song song các hoạt động cá nhân (như bản đồ).

  • Hãy nhìn vào các mô-đun PSeq từ F# PowerPack cho một chiếc F # wrapper thân thiện - đó là định nghĩa pseq<'T> loại và các chức năng thông thường để làm việc với họ. Điều này blog post cũng chứa một số thông tin hữu ích.
+0

cảm ơn. Tôi đã đi qua 'Array.Parallel',' PSeq', và cũng 'ParallelList' trên blog của bạn. Hai cái cuối cùng dường như không được bao gồm trong tham chiếu thư viện, chỉ có 'Array.Parallel'. Tôi đã chỉnh sửa câu hỏi, vui lòng xem. – vis

+1

"làm việc với mảng có lẽ sẽ hiệu quả nhất nếu các hoạt động cá nhân mất một thời gian dài"? Tôi mong đợi các mảng sẽ tương đối nhanh hơn khi các hoạt động cá nhân diễn ra nhanh chóng. –

0

Thực tế, chi phí của các loại thu thập chuyển đổi rất nhỏ so với chi phí thực hiện thao tác không đồng bộ, do đó, loại thu thập không quan trọng.

Có nói rằng, List có xu hướng lưới độc đáo hơn với F # cú pháp để nó có thể là đẹp nhất

+4

'danh sách' là loại bộ sưu tập tồi tệ nhất có thể cho lập trình song song vì nó gây xáo trộn tuần tự. –

1

Cùng với đề xuất của Tomas để xem Array.Parallel, cần lưu ý rằng mảng (và các bộ sưu tập theo mảng) sẽ luôn hiệu quả nhất để duyệt qua (bản đồ, lặp, ...). trong bộ nhớ liền kề.

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