2011-01-05 39 views
18

Tôi hiểu rằng TPL mới (Thư viện song song nhiệm vụ) đã thực hiện Parallel.ForEach() sao cho nó hoạt động với "thuyết trình song song". Có nghĩa là, nó không đảm bảo rằng các đại biểu của bạn sẽ chạy trong nhiều luồng, nhưng thay vào đó nó kiểm tra xem nền tảng máy chủ có nhiều lõi hay không, và nếu đúng, chỉ sau đó nó phân phối công việc trên các lõi (về cơ bản 1 luồng trên mỗi lõi) ..NET 4 ... Parallel.ForEach() question

Nếu hệ thống lưu trữ không có nhiều lõi (khó tìm và khó tìm thấy một máy tính như vậy) thì nó sẽ chạy mã của bạn theo thứ tự giống như vòng lặp foreach thông thường. Khá thú vị, thẳng thắn.

Thông thường tôi sẽ làm một cái gì đó như sau để đặt hoạt động dài chạy của tôi trên một sợi nền từ ThreadPool:

ThreadPool.QueueUserWorkItem (mới WaitCallback (targetMethod), mới Object2PassIn());

Trong trường hợp máy tính chủ chỉ có một lõi đơn, Parallel.ForEach() của TPL tự động đặt lệnh gọi trên một chuỗi nền? Hoặc, tôi có nên gọi manaully bất kỳ cuộc gọi TPL nào từ một nền tảng để nếu tôi đang thực hiện từ một máy tính lõi đơn ít nhất là logic đó sẽ được tắt của thread dispatching của GUI?

Mối quan tâm của tôi là nếu tôi rời TPL phụ trách tất cả điều này, tôi muốn đảm bảo nếu nó xác định đó là một hộp lõi duy nhất mà nó vẫn khắc phục mã bên trong vòng lặp Parallel.ForEach() trên một chuỗi nền như tôi đã làm, để không chặn GUI của tôi.

Cảm ơn mọi suy nghĩ hoặc lời khuyên mà bạn có thể có ...

+1

Chỉ cần theo dõi nhanh về điều này: TPL Rocks! Không thể vượt qua nhanh hơn tôi có thể tạo ra nhiều ứng dụng khác nhau chỉ với một vài điều chỉnh nhỏ bằng cách sử dụng các cuộc gọi TPL so với giá vé "tiêu chuẩn". Tôi đang xem thời gian xử lý trên các mặt hàng khác nhau được cắt giảm lên tới 80%. MS thực sự gõ nó ra khỏi công viên trên này - những người làm việc tuyệt vời. – BonanzaDriver

Trả lời

19

Giả định của bạn không chính xác.
Parallel.For luôn là cuộc gọi chặn.

Ngay cả khi máy tính có nhiều lõi, nó vẫn sẽ chờ tất cả các chuỗi kết thúc trước khi trở về.

Nếu bạn không muốn đóng băng giao diện người dùng, bạn sẽ luôn cần gọi rõ ràng ThreadPool.

+0

Tuyệt vời - nhờ SLaks – BonanzaDriver

+3

Luôn có thể gắn nó vào một Tác vụ và sử dụng tính năng tiếp tục để chờ hoàn thành và sau đó thông báo cho giao diện người dùng. –

0

Tôi nghĩ rằng nếu bạn có yêu cầu chính xác về số lượng mẫu/chuỗi, bạn cần tự làm. Tôi nhận được ấn tượng rằng các loại Parallel.ForEach của các cuộc gọi được cho khai báo lõi nhận được tham gia. Tôi không biết chắc chắn, nhưng tôi có một nghi ngờ lén lút rằng nó sẽ là một lựa chọn tồi cho một cái gì đó mà ngăn chặn i/o (làm ví dụ).

+0

Từ tài liệu tôi đã đọc cho đến nay, nó ban đầu được hình thành cho bộ xử lý sự cố "bộ xử lý". Nhưng, đây không phải là loại trừ việc sử dụng nó cho IO. Trong thực tế, những gì đã cho tôi để có một cái nhìn nghiêm trọng tại TPL là một thực tế rằng tôi có một ứng dụng thực hiện khoảng 7.800 truy vấn web ... Tôi có một hộp xử lý lõi kép quad (3.0 GHz Xeons) đang chạy 24GB RAM trên Windows 7 Ultimate 64-bit edition ... và những người mất ~ 25 đến 28 phút để hoàn thành. Có một số xử lý bổ sung của HTML tải xuống, nhưng bạn nhận được quan điểm của tôi. Tôi đã thay đổi điều này thành một cuộc gọi TPL và mất khoảng 5 phút. – BonanzaDriver

0

Câu hỏi hay. Tôi cho rằng nó vẫn sẽ sinh ra một sợi chỉ ngay cả khi chỉ có một lõi đơn.

Tôi sẽ phải chạy thử nghiệm trên một máy tính lõi đơn. Vì tôi không có, tôi sẽ sử dụng máy ảo và đặt CPU môi trường thành 1 và xem có bao nhiêu luồng mà Parallel ForEach sẽ sinh ra.

Bạn có thể muốn đọc phần sau đây:

Does Parallel limit the Number of Active Threads

1

Qua kinh nghiệm của tôi với Parallel.ForEach và Parallel.For vòng, tôi đã nhận thấy rằng thứ tự có thể được ra khỏi trật tự, một cái gì đó bạn có thể muốn để xem xét trước khi bạn thực hiện.

Chẳng hạn như một cơ sở cho vòng lặp sẽ sản xuất:

sản phẩm 1 Sản phẩm 2 sản phẩm 3 sản phẩm 4

Và vòng lặp song song có thể sản xuất, nhưng không phải lúc nào:

sản phẩm 3 Sản phẩm 1 Sản phẩm 2 Sản phẩm 4

Chỉ cần lưu ý rằng các bạn trẻ.