Tôi đã thực hiện một số công việc tính toán chuyên sâu trong F #. Các hàm như Array.Parallel.map
sử dụng Thư viện song song tác vụ .Net đã tăng tốc mã của tôi theo cấp số nhân cho một nỗ lực thực sự rất nhỏ.F # PSeq.iter dường như không sử dụng tất cả các lõi
Tuy nhiên, do lo ngại về bộ nhớ, tôi làm lại một phần mã của mình để có thể được đánh giá một cách lười biếng bên trong biểu thức trình tự (điều này có nghĩa là tôi phải lưu trữ và chuyển ít thông tin hơn). Khi nó đến thời gian để đánh giá tôi đã sử dụng:
// processor and memory intensive task, results are not stored
let calculations : seq<Calculation> = seq { ...yield one thing at a time... }
// extract results from calculations for summary data
PSeq.iter someFuncToExtractResults results
Thay vì:
// processor and memory intensive task, storing these results is an unnecessary task
let calculations : Calculation[] = ...do all the things...
// extract results from calculations for summary data
Array.Parallel.map someFuncToExtractResults calculations
Khi sử dụng bất kỳ chức năng Array.Parallel tôi có thể thấy rõ ràng tất cả các lõi trên máy tính của tôi đá vào bánh (~ Sử dụng CPU 100%). Tuy nhiên bộ nhớ bổ sung cần thiết có nghĩa là chương trình không bao giờ kết thúc.
Với phiên bản PSeq.iter khi tôi chạy chương trình, chỉ có khoảng 8% sử dụng CPU (và sử dụng RAM tối thiểu).
Vì vậy: Có lý do nào khiến phiên bản PSeq chạy chậm hơn nhiều không? Có phải vì đánh giá lười biếng không? Có một số công cụ "song song" ma thuật mà tôi đang thiếu không?
Cảm ơn,
nguồn lực khác, việc triển khai mã nguồn của cả hai (họ dường như sử dụng thư viện song song khác nhau trong NET):
https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/array.fs
https://github.com/fsharp/powerpack/blob/master/src/FSharp.PowerPack.Parallel.Seq/pseq.fs
EDIT: Thêm nhiều chi tiết về các ví dụ và chi tiết mã số
Code:
Seq
// processor and memory intensive task, results are not stored let calculations : seq<Calculation> = seq { for index in 0..data.length-1 do yield calculationFunc data.[index] } // extract results from calculations for summary data (different module) PSeq.iter someFuncToExtractResults results
Mảng
// processor and memory intensive task, storing these results is an unnecessary task let calculations : Calculation[] = Array.Parallel.map calculationFunc data // extract results from calculations for summary data (different module) Array.Parallel.map someFuncToExtractResults calculations
chi tiết:
- Các lưu trữ các intermediat Phiên bản e array chạy nhanh (theo như trước khi bị lỗi) dưới 10 phút nhưng sử dụng ~ 70GB RAM trước khi nó bị treo (64 GB vật lý, phần còn lại được phân trang)
- Phiên bản seq chiếm hơn 34 phút và sử dụng một phần RAM (chỉ khoảng 30GB)
- Có ~ một tỷ giá trị tôi đang tính toán. Do đó một tỷ đôi (với 64bits mỗi) = 7.4505806GB. Có nhiều dạng dữ liệu phức tạp hơn ... và một số bản sao không cần thiết tôi đang dọn dẹp do đó sử dụng RAM lớn hiện tại.
- Có kiến trúc không tuyệt vời, việc đánh giá lười biếng là phần đầu tiên của tôi cố gắng tối ưu hóa chương trình và/hoặc chuyển hàng loạt dữ liệu thành các đoạn nhỏ hơn
- Với tập dữ liệu nhỏ hơn, cả hai đoạn mã đầu ra giống nhau các kết quả.
- @pad, tôi đã thử những gì bạn đề xuất, PSeq.lặp lại dường như hoạt động đúng (tất cả các lõi hoạt động) khi được tính toán [], nhưng vẫn còn vấn đề RAM (nó cuối cùng đã bị rơi)
- cả phần tóm tắt của mã và phần tính toán là CPU chuyên sâu (chủ yếu là vì các bộ dữ liệu lớn)
- với phiên bản Seq tôi chỉ nhằm mục đích để parallelize lần
Đánh giá lười biếng không hoạt động tốt với thực thi song song. Để công bằng, hãy chuyển cùng một 'Tính toán []' thành 'PSeq.iter' và' Array.Parallel.map'. Không thể nói lý do mà không có thêm chi tiết về 'Calculation' và' someFuncToExtractResults'. – pad
Cảm ơn bạn đã gợi ý, tôi đã thử cách này và PSeq hoạt động tốt khi được đưa vào mảng thay thế trên thiết bị thu gọn ... tuy nhiên nó không giải quyết vấn đề RAM –