5

Tôi có List<byte[]> và tôi muốn deserialize từng byte[] thành Foo. Danh sách được sắp xếp và tôi muốn viết một vòng lặp song song trong đó kết quả List<Foo> chứa tất cả Foo theo thứ tự giống với số byte[] gốc. Danh sách là lớn đáng kể để làm cho hoạt động song song đáng giá. Có cách tích hợp để thực hiện việc này không?Parallel.ForEach trong khi giữ lại đơn hàng

Nếu không, bất kỳ ý tưởng nào để đạt được tốc độ vượt qua tất cả hoạt động này một cách đồng bộ?

Cảm ơn

+0

đăng một số mã mẫu, vui lòng và để ghi lại những điều song song không nhất thiết phải nhanh hơn và hiệu quả hơn ... Wonder if Parallel.For sẽ giải quyết được sự cố của bạn. – adt

+3

Đây là một bản sao từ điều này: http://stackoverflow.com/questions/3639768/parallel-foreach-ordered-execution Vì vậy, để trả lời, bạn có thể sử dụng PLINQ (AsOrdered, AsParallel) để hoàn thành công việc. – Kadelka

+0

Sẽ tốt hơn nếu có tương đương song song với 'Chọn' hoặc' Bản đồ' để giữ lại thứ tự đầu vào. – leppie

Trả lời

4

Từ thông tin bạn' đã đưa ra, tôi hiểu bạn muốn có một mảng đầu ra của Foo với kích thước bằng với mảng đầu vào của byte? Điều này có đúng không?

Nếu vậy, có thao tác rất đơn giản. Đừng bận tâm với việc khóa hoặc đồng bộ các cấu trúc, chúng sẽ làm xói mòn tất cả tốc độ mà sự song song đó mang lại cho bạn.

Thay vào đó, nếu bạn tuân theo quy tắc đơn giản này bất kỳ thuật toán có thể được song song mà không cần khóa hoặc đồng bộ hóa:

Đối với mỗi yếu tố đầu vào X [i] xử lý, bạn có thể đọc từ bất kỳ yếu tố đầu vào X [j], nhưng chỉ viết thư cho yếu tố đầu ra Y [i]

enter image description here

Tra cứu Scatter/Thu thập, loại hình này hoạt động được gọi là một tập hợp như chỉ có một yếu tố đầu ra được ghi vào.

Nếu bạn có thể sử dụng nguyên tắc trên thì bạn muốn tạo mảng đầu ra Foo [] lên phía trước và sử dụng Parallel.For không ForEach trên mảng đầu vào.

Ví dụ:

 List<byte[]> inputArray = new List<byte[]>(); 
     int[] outputArray = new int[inputArray.Count]; 

     var waitHandle = new ManualResetEvent(false); 
     int counter = 0; 

     Parallel.For(0, inputArray.Count, index => 
      { 
       // Pass index to for loop, do long running operation 
       // on input items 
       // writing to only a single output item 
       outputArray[index] = DoOperation(inputArray[index]); 

       if(Interlocked.Increment(ref counter) == inputArray.Count -1) 
       { 
        waitHandle.Set(); 
       } 
      }); 

     waitHandler.WaitOne(); 

     // Optional conversion back to list if you wanted this 
     var outputList = outputArray.ToList(); 
+0

Đánh dấu câu trả lời của bạn là giải pháp mong muốn, mặc dù cuối cùng tôi đã đi với một IPropagatorBlock tùy chỉnh và TPLDataflow thông qua sự giúp đỡ của svick. Mặc dù cả hai, câu hỏi này và dataflow dường như hai khái niệm rất khác nhau ở bề mặt, song song xử lý các khối dữ liệu trong IPropagatorBlock bao la vượt trội hơn bất kỳ vòng lặp Parallel.For liên quan đến vấn đề cụ thể của tôi. Tôi thấy rằng chi phí đồng bộ hóa của việc lập bản đồ và thông báo hoàn thành là rất tốn kém và TPL Dataflow nhắm vào các kịch bản như của tôi. Nhưng điều này không hề giảm giá giải pháp của bạn cho câu hỏi cụ thể của tôi ... –

+0

... không bao gồm vấn đề đồng bộ hóa và thông báo hoàn thành. Đó là về Parallel.Foreach trong khi giữ lại trật tự và giải pháp đề xuất của bạn phù hợp với dự luật. Cảm ơn rất nhiều. –

+0

Điểm tốt! Thư viện song song tác vụ là một giải pháp vượt trội. Tôi ngạc nhiên là nó hoạt động tốt hơn. Có lẽ nó điều chỉnh nhiệm vụ để thực hiện nhiều hơn một serialization cho mỗi chủ đề? Ở trên, bạn có thể bao gồm thông báo đầy đủ với một bộ đếm nguyên và 'Interlocked.Increment (ref counter)' để kiểm tra xem tất cả các phần tử đã được xử lý chưa. Sau đó thiết lập một waithandle để tiến hành. –

2

Bạn có thể sử dụng một từ điển threadsafe với một phím chỉ số int để lưu trữ các reult từ foo nên cuối cùng bạn sẽ có tất cả những người đặt hàng dữ liệu trong từ điển

+0

Cảm ơn, tôi biết điều đó nhưng nghe có vẻ phức tạp. Tôi về cơ bản cần một thủ tục đầy đủ để chờ đợi cho đến tiếp theo Foo lên kế tiếp theo thứ tự, kiểm tra đồng bộ, và thêm các mục theo thứ tự đúng vào danh sách kết quả. Có vẻ như khá nhiều chi phí có thể đánh bại toàn bộ khái niệm chạy song song này. –

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