9

Tôi tự hỏi liệu có ai trong số các bạn biết tại sao hiệu suất của tôi là khủng khiếp hay không;Song song với khung thực thể. Hiệu suất rất ấn tượng so với việc khởi chạy nhiều tệp thực thi, tại sao?

Điều tôi đang cố gắng đạt được; Tạo 2,2 triệu tệp. Để tạo mỗi tệp, cần trung bình 2-5 databasecalls.

Máy chủ tôi đang làm việc trên có 24 lõi và 190 GB bộ nhớ RAM.

Tôi chia các tệp tôi cần tạo thành 24 loạt.

Tôi sử dụng mã sau đây, tôi nhận được hiệu suất tệ hại. Quá trình tạo ra mất hơn một giờ.

Parrallel.ForEach(batches, batch => 
{ 
    using (var ctx = new MyContext()) 
    { 
     for each(var file in batch.Files) 
     { 
      GenerateFile(file); 
     } 
    } 
}); 

Tuy nhiên, khi tôi đảm bảo rằng chương trình của tôi nhận được thông số để progam biết tạo đợt nào nên tôi không cần sử dụng chức năng song song. Nếu tôi thực hiện chương trình cho mỗi lô với tệp .bat sau đây;

START CaMaakEiBericht.exe \B1 
START CaMaakEiBericht.exe \B2 
... 
START CaMaakEiBericht.exe \B24 

Nó chạy rất nhanh! Quá trình tạo tổng số mất ít hơn 15 phút! Tập tin batch này cũng đảm bảo rằng mỗi lõi có mức sử dụng CPU khoảng 90%. Khi tôi sử dụng cách tiếp cận song song, tôi chỉ nhận được 30-40% sử dụng.

Có ai đó có giải thích hợp lý cho điều này không? Tôi đã hài lòng với dự án này vì cuối cùng tôi đã có khả năng sử dụng thư viện song song .NET 4 kết hợp với EF nhưng không may, nó đã làm tôi thất vọng :-)

Cá nhân tôi có một chút nghi ngờ rằng EF là nút cổ chai ở đây ... Có bộ đệm ẩn một số nội dung trong đó áp đặt một số khóa khi nhiều quy trình đang tìm nạp dữ liệu không?

soi sáng cho tôi :-)

+0

Bạn đang sử dụng phiên bản EF nào? –

+0

Có giới hạn áp đặt bởi bộ điều hợp db trên số lượng kết nối cho mỗi chương trình không? Một số bộ điều hợp có loại vấn đề đó, giống như HttpWebRequest. – em70

+0

@ emaster70 - bạn có thể đang ở một mục nào đó, http://stackoverflow.com/questions/3526617/are-ado-net-2-0-connection-pools-pre-application-domain-or-per-process –

Trả lời

4

tôi không thể nói là tại sao tập tin EXE khác của bạn hoạt động tốt, nhưng tôi có thể đưa ra một gợi ý cho các mã mà bạn hiện diện.

Bạn đã đề cập rằng bạn chia công việc của mình thành 24 lô, khi đó bạn đã sử dụng ForEach trong danh sách các lô. Với thiết lập này, có vẻ như mỗi lõi trong số 24 lõi của chúng tôi có thể hoạt động trên 1 tệp tại một thời điểm. Tôi đoán đó là nút cổ chai của bạn.

Mỗi lõi có thể hoạt động nhiều hơn nếu bạn để nó. Hãy thử một cái gì đó như thế này:

Parallel.ForEach(batches, batch => 
{ 
    Parallel.ForEach(batch.Files, file => 
    { 
     using (var ctx = new MyContext()) 
     { 
      GenerateFile(file); 
     }  
    } 
});

Hoặc bạn có thể loại bỏ hoàn toàn các lô và cung cấp danh sách đầy đủ các tệp. Thư viện song song nhiệm vụ sẽ xử lý việc sử dụng nhiều lõi cho bạn.

Parallel.ForEach(Files, file => 
{ 
    using (var ctx = new MyContext()) 
    { 
     GenerateFile(file); 
    }  
});

Bạn có thể đã biết điều này, nhưng hãy nhớ rằng context is not thread safe, vì vậy bạn phải tạo một hình mới bên trong cấu trúc nội nhất Parallel.ForEach.