Tôi đang cố gắng hiểu tại sao Parallel.For có thể làm tốt hơn một số chủ đề trong kịch bản sau: xem xét một loạt công việc có thể được xử lý song song. Trong khi xử lý các công việc này, công việc mới có thể được thêm vào, sau đó cũng cần được xử lý. Các giải pháp Parallel.For
sẽ trông như sau:Parallel.For vs thường xuyên chủ đề
var jobs = new List<Job> { firstJob };
int startIdx = 0, endIdx = jobs.Count;
while (startIdx < endIdx) {
Parallel.For(startIdx, endIdx, i => WorkJob(jobs[i]));
startIdx = endIdx; endIdx = jobs.Count;
}
Điều này có nghĩa rằng có rất nhiều lần nơi Parallel.For cần phải đồng bộ hóa. Hãy xem xét một thuật toán thuật toán đồ thị-bánh mì đầu tiên; số lượng đồng bộ hóa sẽ khá lớn. Lãng phí thời gian, phải không?
Cố gắng giống nhau trong cách tiếp cận luồng old-fashioned:
var queue = new ConcurrentQueue<Job> { firstJob };
var threads = new List<Thread>();
var waitHandle = new AutoResetEvent(false);
int numBusy = 0;
for (int i = 0; i < maxThreads; i++)
threads.Add(new Thread(new ThreadStart(delegate {
while (!queue.IsEmpty || numBusy > 0) {
if (queue.IsEmpty)
// numbusy > 0 implies more data may arrive
waitHandle.WaitOne();
Job job;
if (queue.TryDequeue(out job)) {
Interlocked.Increment(ref numBusy);
WorkJob(job); // WorkJob does a waitHandle.Set() when more work was found
Interlocked.Decrement(ref numBusy);
}
}
// others are possibly waiting for us to enable more work which won't happen
waitHandle.Set();
})));
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());
Các Parallel.For
code đang tất nhiên sạch hơn nhiều, nhưng những gì tôi không thể hiểu được, nó thậm chí còn nhanh hơn nữa! Trình lên lịch nhiệm vụ có tốt không? Các đồng bộ hóa đã được làm nổi bật, không có chờ đợi bận rộn, nhưng cách tiếp cận luồng luôn luôn chậm hơn (đối với tôi). Chuyện gì vậy? Cách tiếp cận luồng có thể được thực hiện nhanh hơn không?
Chỉnh sửa: cảm ơn tất cả các câu trả lời, tôi ước tôi có thể chọn nhiều câu trả lời. Tôi đã chọn để đi với một trong đó cũng cho thấy một cải tiến thực tế có thể.
Tại sao bạn muốn thử và làm cho nó nhanh hơn nếu đã có một giải pháp sạch hơn nhanh hơn? – iMortalitySX
Bởi vì có một sự thiếu hụt rõ ràng có thể được loại bỏ, tôi nghĩ vậy. –
Đóng câu hỏi [PLinq có nhanh hơn System.Threading.Tasks.Parallel.ForEach] không (http://stackoverflow.com/questions/5196293/is-plinq-inherently-faster-than-system-threading-tasks-parallel- foreach) – iMortalitySX