2011-01-02 27 views
29

Tôi đang cố gắng để hiểu tại sao chúng ta cần tất cả các phần của mã mẫu tiêu chuẩn:Tại sao chúng ta cần 'seq' hoặc 'pseq' với 'par' trong Haskell?

a `par` b `pseq` a+b 

Tại sao sẽ không sau đây là đủ?

a `par` b `par` a+b 

Các biểu thức trên có vẻ rất mô tả: Cố gắng để đánh giá cả ab song song, và trả lại kết quả a+b. Là lý do duy nhất hiệu quả: phiên bản thứ hai sẽ phát ra hai lần thay vì một lần?

Phiên bản ngắn gọn hơn, ngắn gọn hơn như thế nào?

a `par` a+b 

Tại sao chúng ta cần phải chắc chắn b được đánh giá trước khi a+b như trong bản gốc, mã tiêu chuẩn?

Trả lời

29

Ok. Tôi nghĩ rằng giấy tờ sau đây trả lời câu hỏi của tôi: http://community.haskell.org/~simonmar/papers/threadscope.pdf

Tóm lại, vấn đề với

a `par` b `par` a+b 

a `par` a+b 

là thiếu Trật tự của các đánh giá. Trong cả hai phiên bản, thread chính được làm việc trên a (hoặc đôi khi b) ngay lập tức, khiến các tia lửa "nhanh chóng bị lóa" ngay lập tức vì không cần phải bắt đầu một chuỗi để đánh giá chủ đề chính đã bắt đầu đánh giá.

Phiên bản gốc

a `par` b `pseq` a+b 

đảm bảo các chủ đề chính hoạt động trên btrướca+b (hoặc nếu không có thể đã bắt đầu đánh giá a thay), do đó đem lại một cơ hội cho các tia lửa a trở thành hiện thực vào một thread cho đánh giá song song.

+6

Điều này đúng và cũng giải thích tại sao 'seq' không đủ cho vấn đề này. 'seq' không đảm bảo về thứ tự đánh giá. Trong 'seq b (a + b)', luồng chính có thể đánh giá 'a' trước' b' miễn là 'b' nằm trong WHNF khi' (a + b) 'được đánh giá. –

+2

Tôi không thấy cách đối số đó mô tả vấn đề với 'par a (mệnh b (a + b))' - chắc chắn, hoặc 'a' hoặc' b' sẽ được đánh giá ngay lập tức, và tia lửa tương ứng sẽ biến mất, nhưng tia lửa khác nên sống rất nhiều, tạo ra sự song song. Tất nhiên, tạo ra sau đó fizzling một tia lửa có thể không phải là cách hiệu quả nhất để làm điều này, nhưng nó hoạt động và để lại câu hỏi để đánh giá trình biên dịch. – gereeter

+0

Trong trường hợp của 'par a (a + b)', nó vẫn có thể nhận được một "may mắn" song song, nếu thời gian chạy thay vì chọn 'b' đầu tiên. Sau đó, tia lửa "a' sẽ không bị xáo trộn. Điều này được đề cập trong PDF: community.haskell.org/~simonmar/papers/threadscope.pdf (trang 2) – CMCDragonkai

16
a `par` b `par` a+b 

sẽ đánh giá a và b song song và trả a + b, vâng.

Tuy nhiên, pseqđảm bảo cả a và b được đánh giá trước khi a + b là.

Xem this link để biết thêm chi tiết về chủ đề đó.

6

a `par` b `par` a+b tạo ra tia lửa cho cả ab, nhưng a+b đạt được ngay lập tức để một trong những tia lửa sẽ xì hơi nhanh chóng (ví dụ, nó được đánh giá trong các chủ đề chính). Vấn đề với điều này là hiệu quả, khi chúng tôi tạo ra một tia lửa không cần thiết. Nếu bạn đang sử dụng điều này để thực hiện chia song song & chinh phục thì phí trên sẽ giới hạn tốc độ của bạn.

a `par` a+b có vẻ tốt hơn vì nó chỉ tạo ra một tia lửa đơn. Tuy nhiên, việc cố gắng đánh giá a trước khi b sẽ làm xáo trộn tia lửa cho a và do b không có tia lửa này sẽ dẫn đến đánh giá tuần tự là a+b. Việc chuyển đơn đặt hàng sang b+a sẽ giải quyết vấn đề này, nhưng khi mã này không thực thi thứ tự và Haskell vẫn có thể đánh giá đó là a+b.

Vì vậy, chúng tôi thực hiện a `par` b `pseq` a+b để buộc đánh giá b trong luồng chính trước khi chúng tôi cố gắng đánh giá a+b. Điều này mang lại cho cơ hội phát tia lửa a trước khi chúng tôi thử đánh giá a+b và chúng tôi chưa tạo bất kỳ tia lửa không cần thiết nào.

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