Tôi không nghĩ danh sách là loại dữ liệu phù hợp cho việc này. Bởi vì nó chỉ là một danh sách liên kết, dữ liệu nhất thiết sẽ được truy cập tuần tự. Mặc dù bạn có thể đánh giá các mục song song, bạn sẽ không đạt được nhiều trong bước giảm. Nếu bạn thực sự cần một danh sách, tôi nghĩ rằng chức năng tốt nhất là chỉ
parFold f = foldl1' f . withStrategy (parList rseq)
hoặc có thể
parFold f = foldl1' f . withStrategy (parBuffer 5 rseq)
Nếu bước giảm rất phức tạp, bạn có thể có được một lợi bởi phân chia danh sách như thế này:
parReduce f = foldl' f mempty . reducedList . chunkList . withStrategy (parList rseq)
where
chunkList list = let (l,ls) = splitAt 1000 list in l : chunkList ls
reducedList = parMap rseq (foldl' f mempty)
tôi đã lấy sự tự do của giả định dữ liệu của bạn là một Monoid
cho mempty, nếu điều này là không thể bạn có thể thay thế mempty với loại sản phẩm nào của riêng bạn, hoặc tệ hơn trường hợp sử dụng foldl1'
.
Có hai toán tử từ Control.Parallel.Strategies
được sử dụng tại đây. Các parList
đánh giá tất cả các mục của danh sách song song. Sau đó, chunkList
chia danh sách thành các phần của 1000 phần tử. Mỗi khối này sau đó được giảm song song với parMap
.
Bạn cũng có thể thử
parReduce2 f = foldl' f mempty . reducedList . chunkList
where
chunkList list = let (l,ls) = splitAt 1000 list in l : chunkList ls
reducedList = parMap rseq (foldl' f mempty)
Tùy thuộc vào chính xác cách thức các công việc được phân phối, một trong những có thể hiệu quả hơn những người khác.
Nếu bạn có thể sử dụng cấu trúc dữ liệu có hỗ trợ tốt cho việc lập chỉ mục (Array, Vector, Map, vv), thì bạn có thể làm phân mục nhị phân cho bước giảm, có thể sẽ tốt hơn.
Như mọi người đã lưu ý, danh sách là cấu trúc dữ liệu kém để chia nhỏ song song đệ quy. Bạn muốn một số loại cấu trúc cây/dây nhị phân như trong ngôn ngữ Pháo đài: http://labs.oracle.com/projects/plrg/Publications/ICFPAugust2009Steele.pdf – sclv