2012-01-19 36 views
20

Hôm nay tôi đã thử thực hiện một số tối ưu hóa cho câu lệnh foreach, hoạt động trên XDocument.Tại sao Parallel.ForEach không chạy nhiều luồng?

Trước khi tối ưu hóa:

foreach (XElement elem in xDoc.Descendants("APSEvent").ToList()) 
{ 
    //some operations 
} 

Sau khi tối ưu hóa:

Parallel.ForEach(xDoc.Descendants("APSEvent").ToList(), elem => 
{ 
    //same operations 
}); 

tôi thấy rằng NET trong Parallel.ForEach(...) mở CHỈ một thread! Kết quả là khoảng thời gian của Parallel lớn hơn tiêu chuẩn foreach.

Tại sao bạn nghĩ .NET chỉ mở 1 chuỗi? Bởi vì khóa tập tin? Cảm ơn

+10

Có bao nhiêu lõi hoặc bộ vi xử lý logic trong máy của bạn? Có bao nhiêu phần tử trong danh sách? –

+0

Tôi không thể thấy bất kỳ mối quan hệ nào của tiêu đề cho câu hỏi. –

+0

Christian.K, tôi có máy chủ với bộ xử lý Xeon và ram 8GB (Dell PowerEdge R210) với MS Server2008 OS. Tôi nghĩ rằng, nó không phụ thuộc vào bao nhiêu yếu tố tôi có trong tài liệu XML, tôi nghĩ rằng hình phạt thời gian là do khóa tập tin. – zzfima

Trả lời

14

Đó là do thiết kế mà Parallel.ForEach có thể sử dụng bài ít hơn yêu cầu để đạt được hiệu suất tốt hơn. Theo MSDN [link]:

Theo mặc định, các phương thức Parallel.ForEach và Parallel.For có thể sử dụng một số tác vụ khác nhau. Đó là lý do tại sao, ví dụ, lớp ParallelOptions có một tài sản MaxDegreeOfParallelism thay vì một thuộc tính "MinDegreeOfParallelism". Ý tưởng là hệ thống có thể sử dụng ít chuỗi hơn yêu cầu để xử lý vòng lặp.

Nhóm chủ đề .NET điều chỉnh động để thay đổi khối lượng công việc bằng cách cho phép số lượng chuỗi công việc cho các tác vụ song song thay đổi theo thời gian. Vào thời gian chạy, hệ thống quan sát xem việc tăng số lượng các luồng có cải thiện hay làm suy giảm toàn bộ thông lượng và điều chỉnh số lượng các chuỗi công việc cho phù hợp hay không.

0

Có chính xác, Document.Load(...)locks the file và do nguồn lực tranh chấp giữa các chủ đề, TPL là không thể sử dụng sức mạnh của nhiều chủ đề. Hãy thử tải XML thành Stream và sau đó sử dụng Parallel.For(...).

+6

Điều đó sẽ chỉ giải thích lý do tại sao chỉ có một luồng _đưa ra tiến trình_, không phải lý do tại sao chỉ có một luồng là _created_ - như là tuyên bố OP. 'Parallel.ForEach' không thể (một cách hợp lý) có bất kỳ kiến ​​thức nào về bộ sưu tập mà nó đang lặp lại (nó chỉ" thấy "một danh sách' Danh sách 'được truyền vào và nó là không hợp lý để giả định rằng nó có bất kỳ triển khai đặc biệt nào cho điều đó). Ngoài ra, 'ToList' về cơ bản lấy tất cả các phần tử háo hức, do đó, khóa (và thực tế là nó được đọc từ một tập tin) không nên thực hiện bất kỳ sự khác biệt ở đây. –

-1

Bạn có muốn có một bộ xử lý không? TPL có thể giới hạn số lượng chủ đề thành một trong trường hợp này. Điều tương tự có thể xảy ra nếu bộ sưu tập rất nhỏ. Hãy thử một bộ sưu tập lớn hơn. Xem this answer để biết thêm chi tiết về cách xác định mức độ song song.

+2

Trò đùa của câu trả lời. Có lẽ thích hợp như một bình luận. – Mukus

1

sử dụng nó như thế này:

int ParallelThreads = 10; 
Parallel.ForEach(xDoc.Descendants("APSEvent").ToList(), new ParallelOptions() { MaxDegreeOfParallelism = ParallelThreads }, (myXDOC, i, j) => 
{ 
//do whatever you want here 
}); 
+0

Chỉ cần lưu ý rằng MaxDegreeOfParallelism đặt số lượng chủ đề tối đa, không tối thiểu. Vì vậy, hữu ích khi bạn muốn giới hạn hoặc giảm số lượng các luồng/lõi được sử dụng. – coloboxp

1

Từ mô tả sự cố, không có gì giải thích tại sao TPL không sinh ra nhiều chuỗi hơn.

Không có bằng chứng nào trong câu hỏi thậm chí là vấn đề. Điều đó có thể được sửa chữa khá dễ dàng: bạn có thể đăng nhập id thread, trước khi bạn nhập vòng lặp, và như là điều đầu tiên bạn làm bên trong vòng lặp của bạn.

Nếu nó luôn luôn là cùng một số, đó là TPL không sinh ra chủ đề. Sau đó, bạn nên thử các phiên bản khác nhau của mã của mình và những thay đổi nào kích hoạt TPL để tuần tự hóa mọi thứ. Một lý do có thể là nếu có một số lượng nhỏ các yếu tố trong danh sách của bạn.TPL phân vùng bộ sưu tập của bạn và nếu bạn chỉ có một vài mục, bạn có thể kết thúc chỉ với một lô. Hành vi này được cấu hình bằng cách này.

Có thể bạn đang vô ý lấy khóa trong vòng lặp, sau đó bạn sẽ thấy nhiều số khác nhau, nhưng không có tăng tốc. Sau đó, đơn giản hóa mã cho đến khi vấn đề biến mất.

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