9

Sizden herhangi birinin, performansımın neden berbat olduğunu biliyor musunuz?. Performans, çok sayıda çalıştırılabilirliğe kıyasla dramatiktir, neden?

Neyi başarmaya çalışıyorum; 2.2 milyon dosya üretin. Her dosyayı oluşturmak için, ortalama 2-5 veri tabanına ihtiyaç vardır.

Üzerinde çalıştığım sunucunun 24 çekirdeği ve 190 GB RAM'i var.

Üretmem gereken dosyaları 24 grupta ayırdım.

Aşağıdaki kodu kullanıyorum, kötü performans alıyorum. Üretim süreci bir saatten fazla sürüyor. Ben Progam yüzden paralel işlevini kullanmak gerekmez üretmek için hangi parti bilmesi için benim program bir parametre almasını sağlamak Ancak

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

. Her toplu iş için programı aşağıdaki .bat dosyası ile çalıştırırsam;

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

Çok hızlı çalışır! Toplam üretim süreci 15 dakikadan az sürüyor! Bu toplu iş dosyası ayrıca her çekirdeğin% 90 civarında bir cpu kullanımına sahip olduğundan emin olur. Paralel yaklaşımı kullandığımda, sadece% 30-40 kullanımım olur.

Bunun için birisinin mantıklı bir açıklaması var mı? Bu projeden memnun kaldım çünkü sonunda EF ile birlikte .NET 4 Paralel kütüphanesini kullanma imkanım vardı ama ne yazık ki, beni hayal kırıklığına uğrattı :-)

Şahsen buradaki darboğazın hafif bir şüphesi var. ... Birden fazla işlem veri aldığında bazı kilitleri dayatan dahili olarak bazı şeyleri önbelleğe alıyor mu?

+0

Hangi EF sürümünü kullanıyorsunuz? –

+0

db bağdaştırıcısının program başına bağlantı sayısı üzerindeki sınırlamaları var mı? Bazı bağdaştırıcılar, HttpWebRequest gibi bu tür bir soruna sahiptir. – em70

+0

@ emaster70 - http://stackoverflow.com/questions/3526617/are-ado-net-2-0-connection-pools-pre-application-domain-or-per-process –

cevap

4

ben diğer EXE dosyası iyi çalışır neden olarak konuşamıyor :-) Beni aydınlat, ama mevcut kodu için bir öneri sunabilir.

İşinizi 24 gruba ayırdığınızdan bahsettiniz, sonra ForEach'ı toplu iş listesinin üzerine kullandınız. Bu kurulumla, 24 çekirdeğin her birinin aynı anda 1 dosya üzerinde çalışabileceği görülüyor. Benim tahminim bu darboğaz.

İzin verirseniz her bir çekirdek çok daha fazlasını yapıyor olabilir. Böyle bir şey deneyin:

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

Ya da sadece serilerin bütünüyle kurtulmak olabilir ve bu dosyaların tam listesini verir. Paralel kütüphane görevi sizin için birden çok çekirdeğin kullanılmasını sağlayacaktır.

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

Muhtemelen bu biliyorum, ama en iç Parallel.ForEach yapının içinde yeni bir tane oluşturmak zorunda böylece, akılda o context is not thread safe bulundurun.

İlgili konular