Yanıtlar:
Bu sorduğunuz karmaşık bir soru. Dişlerinin yapısı hakkında daha fazla şey bilmeden söylemek zor. Sistem performansını teşhis ederken dikkate alınması gereken bazı şeyler:
İşlem / iş parçacığı mı
Bu üç kaynağın tümü sonludur ve herhangi biri sistemin performansını sınırlayabilir. Özel durumunuzun hangi (2 veya 3 olabileceği) tüketeceğine bakmanız gerekir.
Sen kullanabilirsiniz ntop
ve iostat
ve vmstat
ne olup bittiğini teşhis etmek.
“Bu neden oluyor?” cevaplaması kolay bir şey. Dört kişiyi yan yana yerleştirebileceğiniz bir koridorunuz olduğunu hayal edin. Tüm çöpleri bir ucundan diğer ucuna taşımak istiyorsun. En verimli insan sayısı 4'tür.
Eğer 1-3 kişiniz varsa, o zaman bazı koridor alanlarını kullanmaktan mahrum kalacaksınız. 5 veya daha fazla kişiniz varsa, o zaman bu kişilerden en az biri temelde sürekli başka bir kişinin kuyruğunda kalmış durumda kalır. Gittikçe daha fazla insan eklemek sadece koridoru tıkamaktadır, bu da etkinliği hızlandırmaz.
Demek sıraya girmeden sığabileceğin kadar insanın olmasını istiyorsun. Neden kuyruğa aldığınız (veya tıkanıklıklar) slm'ın cevabındaki sorulara bağlıdır.
4
iyi bir sayıdır.
Yaygın bir öneri n + 1 ipliktir, n mevcut CPU çekirdeği sayısıdır. Bu şekilde n thread, 1 thread disk I / O için beklerken CPU'yu çalıştırabilir. Daha az sayıda iş parçacığı olması CPU kaynağını tam olarak kullanmayacak (bir noktada beklemek için her zaman G / Ç olacaktır), daha fazla iş parçacığı olması iş parçacığı CPU kaynağı üzerinde kavgaya neden olacaktır.
İplikler serbest değil, baş üstü gibi bağlam anahtarları ile birlikte gelir ve - eğer genellikle durum olan dişler arasında veri alışverişi yapılması gerekiyorsa - çeşitli kilitleme mekanizmaları. Bu, yalnızca kodu çalıştırmak için gerçekten daha fazla CPU çekirdeğine sahip olduğunuzda maliyeti düşürür. Tek çekirdekli bir işlemcide, tek bir işlem (ayrı iş parçacığı yok) genellikle yapılan herhangi bir iş parçacığından daha hızlıdır. İş parçacıkları sihirli bir şekilde işlemcinizi daha hızlı çalıştırmaz, bu sadece ekstra çalışma anlamına gelir.
Diğerlerinin de belirttiği gibi ( slm cevap , EightBitTony cevap ) bu karmaşık bir sorudur ve daha fazlası, çünkü ne yaptığınızı ve nasıl yaptıklarını açıklamadığınızdan.
Ancak kesin olarak daha fazla dişe atmak işleri daha da kötüleştirebilir.
Paralel hesaplama alanında, uygulanabilecek Amdahl yasası var (ya da yapamazsınız, ancak problemin ayrıntılarını tanımlamazsınız, bu yüzden ...) ve bu problem sınıfı hakkında bazı genel bilgiler verebilir.
Amdahl yasasının amacı, herhangi bir programda (herhangi bir algoritmada) her zaman paralel olarak çalıştırılamayan bir yüzde ( sıralı kısım ) olduğu ve paralel olarak çalıştırılabilecek başka bir yüzde olduğu ( paralel kısım ) [Açıkçası bu iki bölüm% 100'e kadar ekler].
Bu bölümler yürütme süresinin yüzdesi olarak ifade edilebilir. Örneğin, tamamen ardışık işlemlerde harcanan zamanın% 25'i olabilir ve kalan% 75'lik bir süre paralel olarak gerçekleştirilebilecek olan operasyonda harcanır.
( Wikipedia'dan görüntü )
Amdahl kanunu, bir programın verilen her paralel kısmı (örneğin% 75) için, işi yapmak için daha fazla işlemci kullanıyor olsanız bile, uygulamayı şu ana kadar (örneğin en fazla 4 kez) hızlandırabileceğinizi öngörmektedir.
Genel bir kural olarak, paralel yürütmede dönüştüremediğiniz program ne kadar çok olursa, daha fazla yürütme birimi (işlemci) kullanarak daha az elde edersiniz.
İş parçacığı kullanıyorsanız (ve fiziksel işlemcileri değil) durum bundan daha da kötü olabilir. Konuların aynı fiziksel işlemciyi / çekirdeği (başka bir cevapta belirtildiği gibi paylaşan bir çoklu görev şeklidir ) paylaşan işlenebileceğini (mevcut uygulamaya ve donanıma bağlı olarak, örneğin CPU'lar / Çekirdekler ) unutmayın.
Bu teorik tahmin (CPU zamanları hakkında) diğerlerinin pratik darboğazlarını dikkate almaz
pratik uygulamalarda kolayca sınırlayıcı faktör olabilir.
Buradaki suçlu "CONTEXT SWITCHING" olmalıdır. Başka bir iş parçacığı çalıştırmaya başlamak için geçerli iş parçacığının durumunu kaydetme işlemidir. Bir dizi dişe aynı önceliğe sahip olması durumunda, yürütmeyi bitirene kadar çevrilmeleri gerekir.
Sizin durumunuzda, 50 iş parçacığı olduğunda, sadece 10 iş parçacığı çalıştırmaya kıyasla çok sayıda bağlam değişimi gerçekleşir.
Bağlam geçişi nedeniyle ortaya çıkan genel masraf, programınızın yavaş çalışmasına neden olan şeydir
ps ax | wc -l
225 işlem bildiriyor ve hiçbir şekilde ağır yüklü değil). @ EightBitTony'nin tahminde bulunma eğilimindeyim; önbellek geçersiz kılma büyük olasılıkla daha büyük bir sorundur, çünkü önbelleği her yıkadığınızda, CPU eons'u RAM'den gelen kod ve veriler için beklemelidir .
EightBitTony'nin metaforunu düzeltmek için:
“Bu neden oluyor?” cevaplaması kolay bir şey. Biri dolu diğeri boş olan iki yüzme havuzunuz olduğunu hayal edin . Tüm suyu birinden diğerine taşımak istiyorsunuz ve 4 kovaya sahip olmak istiyorsunuz . En verimli insan sayısı 4'tür.
Eğer 1-3 kişiniz varsa, o zaman bazı kovaları kullanmaktan mahrum kalacaksınız . 5 veya daha fazla kişiniz varsa, o zaman bu kişilerden en az biri bir kepçe bekliyor . Gittikçe daha fazla insan eklemek ... etkinliği hızlandırmıyor.
Yani aynı anda bazı işleri yapabilen (bir kova kullanın) mümkün olduğunca çok insana sahip olmak istiyorsunuz .
Buradaki bir kişi bir ipliktir ve bir kova, hangi yürütme kaynağının darboğaz olduğunu gösterir. Daha fazla iş parçacığı eklemek, bir şey yapamazlarsa yardımcı olmaz. Ek olarak, bir kepçeyi bir kişiden diğerine geçirmenin, sadece kepçeyi aynı mesafeye taşıyan tek bir kişiden genellikle daha yavaş olduğunu vurgulamalıyız . Diğer bir deyişle, bir çekirdeği açan iki diş tipik olarak iki defa uzun süren tek bir dişten daha az iş başarır: bunun nedeni iki diş arasında geçiş yapmak için yapılan fazladan çalışmadır.
Sınırlayıcı yürütme kaynağının (kova) bir CPU mu yoksa bir çekirdek mi, yoksa amaçlarınız için aşırı dişli bir komut borusu olması mimarinin hangi bölümünün sınırlayıcı faktörünüz olduğuna bağlıdır. Ayrıca, dişlilerin tamamen bağımsız olduğunu varsayıyoruz . Bu paylaştıkları yalnızca durumdur hiçbir veri (ve herhangi bir önbellek çarpışmaları önlemek).
Birkaç kişinin önerdiği gibi, G / Ç için sınırlayıcı kaynak, yararlı bir şekilde sıralanabilir G / Ç işlemlerinin sayısı olabilir: bu, bir dizi donanım ve çekirdek faktörüne bağlı olabilir, ancak bu sayıdan çok daha büyük olabilir çekirdekler. Burada, çalıştırma sınırlı kodla karşılaştırıldığında çok pahalı olan bağlam anahtarı, G / Ç sınırlama koduyla karşılaştırıldığında oldukça ucuzdur. Ne yazık ki, bunu kovalarla haklı çıkarmaya çalışırsam metaforun tamamen kontrolden çıkacağını düşünüyorum.
G / Ç bağlı koduyla en uygun davranışın hala her bir boru hattı / çekirdek / CPU başına en fazla bir iş parçacığına sahip olduğunu unutmayın. Ancak, senkronize olmayan veya senkronize olmayan / bloke edici olmayan G / Ç kodu yazmanız gerekir ve nispeten küçük performans iyileştirmesi her zaman ekstra karmaşıklığı haklı çıkarmaz.
PS. Orijinal koridor metaforuyla ilgili sorunum, 4 sıra insanın olabileceği, 2 sıra çöp taşıyan ve 2 daha fazla toplama yapmak için geri dönecek olmanız gerektiğini şiddetle tavsiye ediyor. Sonra koridor olarak neredeyse sürece her kuyruğu yapabilir ve ekleme insanlar yaptılar algoritma yukarı hızını (temelde bir konveyör bant içine bütün koridorunu döndü).
Aslında bu senaryo, TCP ağındaki gecikme ve pencere boyutu arasındaki ilişkinin standart tanımına çok benzer, bu yüzden bana atladı.
Anlaşılması oldukça basit ve basittir. CPU'nuzun desteklediğinden daha fazla iş parçacığına sahip olmak aslında serileştiriyor ve paralelleştirmiyor. Ne kadar çok iş parçacığına sahipseniz, sistem o kadar yavaş olur. Sonuçlarınız aslında bu olgunun bir kanıtı.