Programlamada iş parçacıklarının doğru kullanımını ne oluşturur?


13

İnsanların işlemci başına yalnızca bir iş parçacığı kullanmasını önermekten bıktım, birçok program işlem başına 100'e kadar kullanıyor! örneğin bazı ortak programları ele alalım

vb.net ide uses about 25 thread when not debugging
System uses about 100
chrome uses about 19
Avira uses more than about 50

Ne zaman bir iş parçacığı ile ilgili soru göndermek, neredeyse her zaman işlemci başına bir iş parçacığı daha fazla kullanmam gerektiğini hatırlattı ve yukarıda bahsettiğim tüm programlar tek bir işlemci ile sistemimi mahvediyor.


7
Bu öneri geniş. İşlemci başına bir iş parçacığının sınırı, yalnızca hesaplamaya bağlı uygulamalar için uygundur. Ağ trafiği, disk erişimi ve hatta RAM olsun, çoğu program IO'ya bağlıdır. Bu nedenle web sunucuları, veritabanları vb. İşlemci çekirdeklerinden çok daha fazla iş parçacığına sahip iş parçacığı havuzlarına sahiptir.
Kilian Foth

2
"Her işlemci için birden fazla iş parçacığı kullanmamam gerektiğini hatırlatıyorum"? Bağlantı veya örnek gönderebilir misiniz? Neredeyse her seferinde?
S.Lott

2
“... insanlar her işlem için sadece bir iş parçacığı kullanmanızı tavsiye ediyor.” Bu insanlar kim? Zamanlama, Karanlık Çağlardan beri önemli ölçüde ilerlemiştir.
Rein Henrichs

2
İşlem başına birden fazla UI iş parçacığına sahip olmamalısınız .
SLaks

3
@Billy ONeal, düzenlemeniz soruyu anlamsız hale getirdi
SK-logic

Yanıtlar:


22

işlemci başına yalnızca bir iş parçacığı kullanmalısınız,

Muhtemelen maksimum verimlilik istediğiniz HPC'de - aksi halde bugün duyduğum en aptalca şey!

Programın tasarımına uygun ve yine de kabul edilebilir performans sağlayan iş parçacığı sayısını kullanmalısınız.

Bir web sunucusu için, her gelen bağlantı için bir iş parçacığı başlatmak mantıklı olabilir (ancak çok yüklü sunucular için daha iyi yollar vardır).

Bir taraf için, kendi iş parçacığında çalışan her araç mantıksız değildir. Net IDE için bildirilen iş parçacıklarının çoğunun, bloke edilmeye devam edebilmeleri için kendi iş parçacıklarında başlatılan günlük ve G / Ç görevleri gibi şeyler olduğundan şüpheleniyorum.


9
Şimdi duyduğun en aptal şeyin ne olduğunu merak ettin!
Michael K

3
@Michael - Lisans öğrencilerine ders verdim ve savunma sözleşmeleri üzerinde çalıştım - duyduğum en aptalca şeylere inanmazdın!
Martin Beckett

1
Onları TheDailyWTF.com'da gördük mü?
Hayal kırıklığına

şimdi onları gerçekten bulamıyorum, ama bu bağlantıya bak social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/…
Smith

2
Yazıldı en uygulamaya ayrılmış işlemci için bir CPU bağlı iplik. GÇ'ye bağlı iş parçacıkları büyük bir sorun değildir (tükettikleri bellek dışında) ve uygulamaların yalnızca sistem CPU'larının bir alt kümesini kullanmakla sınırlandırılabileceğini unutmamak önemlidir; sonuçta, programcının değil kullanıcının / yöneticinin bilgisayarı (genellikle).
Donal Fellows

2

Çekirdek başına bir iş parçacığı tavsiyesi, amaç paralel yürütme yoluyla hız olduğunda geçerlidir.

Tamamen farklı ve eşit derecede geçerli bir neden, öngörülemeyen olaylara yanıt vermesi gerektiğinde kodun basitliğidir. Bu nedenle, bir program 100 sokette dinlemeli ve her birine tam olarak dikkat ediyor gibi görünüyorsa, bu, diş çekme için mükemmel bir kullanımdır. Başka bir örnek, bir iş parçacığının kullanıcı arabirimi olaylarını işlediği bir kullanıcı arayüzüdür, diğeri ise arka plan işlemeyi gerçekleştirir.


1
IO-bağlı işleme olay kaynağı başına bir iş parçacığı olarak yapılabilir veya birden fazla olay kaynağı tek bir iş parçacığına çoğaltılabilir. Çoğullamalı kod genellikle hem daha karmaşık hem de daha verimlidir.
Donal Fellows

2

Her hesaplama için diğer hesaplamalardan farklı hızlarda ilerleyebilen bir iş parçacığı istiyorsunuz.

Büyük iş bloklarında gelen paralel CPU-bağlı hesaplama için, genellikle CPU başına bir iş parçacığı istersiniz, çünkü hepsi meşgul olduktan sonra, daha fazla iş parçacığı yardımcı olmaz ve sadece zamanlayıcı yükü oluşturur. Çalışma blokları zaman içinde düzensiz boyutlara sahipse veya çalışma zamanında dinamik olarak oluşturulduysa (genellikle işlemek için büyük karmaşık veri yapılarınız olduğunda olur), bu blokları çok sayıda iş parçacığına eklemek isteyebilirsiniz, bu nedenle bir zamanlayıcı her zaman büyük tüm CPU'ları meşgul etmek için bir iş bloğu tamamlandığında seçim yapmak için ayarlayın.

G / Ç bağlantılı hesaplama için, farklı hızlarda iletişim kurduklarından ve kanalda engellenen iş parçacıkları ilerlemesini engellemediğinden, genellikle her bağımsız G / Ç "kanalı" için bir iş parçacığı istersiniz.


Sadece bu tarz ipliğin bazı garip mimarlık programlarına yol açabileceğini unutmayın. Ben bir DB tablodan kayıtları okumak için bir iş parçacığı, bir sokete dönüştürülmüş kayıtları yazmak için bir iş parçacığı, bu soket yazar cevapları okumak için bir iş parçacığı olan 4 iş parçacıklı bir program gördüm (hangi sıra dışı geldi) ve eşzamansız olarak) ve orijinal DB kaydını yanıtla değiştirmek için bir iş parçacığı. İstenmeyen hata koşulları ortaya çıktı.
Bruce Ediger

Bir görüş, bu tarzın garip programlar üretmesidir. Başka bir görüş, programların sahip olması gereken doğal stildir. "Sezgisel olmayan" hata koşulları hakkında bilmiyorum; çok şey oluyorsa ve bunlardan biri bir hata alırsa, eşzamansız hesaplamalar arasında düzgün bir şekilde yayıldığından emin olmak birçok dil için bir sorundur [aptalca, iş parçacığı sınırlarında Java istisnaları tanımlanmamıştır], ancak değil program stili ile ilgili bir sorun. (PARLANSE programlama dilimiz [biyografime bakın], iplik sınırları arasındaki istisnaları temiz bir şekilde işler, böylece bunu doğru yapmak mümkündür.).
Ira Baxter

1

İş parçacıkları için temel kural, bilgisayarda bulunan her bir "yürütme birimi" için en az bir "etkin" (komutlarının hemen CPU çalıştırılabilmesini sağlayan) çalışan iş parçacığı olmasını istediğinizdir. Bir "yürütme birimi" bir mantıksal komut işlemcisidir, bu nedenle dört çipli, dört çekirdekli Xeon hiper iş parçacıklı sunucunun 32 AB'si vardır (her bir çip için 4 çip, 4 çekirdek, her bir hiper iş parçacığı). Ortalama Core i7'niz 8 olacaktır.

AB başına bir iş parçacığı, iş parçacıklarının her zaman çalışır durumda olması şartıyla CPU'nun gücünü en iyi şekilde kullanır; iş parçacıklarının önbelleğe alınmamış belleğe, sabit diske, ağ bağlantı noktalarına vb. erişmeleri gerektiğinden ve işlem yapmak için etkin CPU dikkatine gerek duymadığından bu neredeyse hiç olmaz. Böylece, daha fazla iş parçacığı kuyruğa alındı ​​ve gittikçe daha fazla ilerledikçe genel verimliliği daha da artırabilirsiniz. Bunun bir bedeli vardır; CPU bir iş parçacığını değiştirdiğinde, iş parçacığının kayıtlarını, yürütme işaretçisini ve normalde bir AB'nin en içteki işlerinde tutulan ve çok hızlı bir şekilde erişilen diğer bilgi işlemlerini önbelleğe almalı ve bu CPU çipindeki diğer AB'lerin onu almasına izin vermelidir. Ayrıca hangi iş parçacığına geçilmesi gerektiğine karar vermek için OS'deki iş parçacıklarını gerektirir. Son olarak, bir AB iş parçacıklarını değiştirdiğinde, çoğu işlemci mimarisinin kullandığı boru hattının performans kazançlarını kaybeder; dişleri değiştirmeden önce boru hattını yıkamalıdır. Ancak, tüm bunlar hala sabit sürücünün veya RAM'in bilgi ile geri gelmesini beklemekten ortalama olarak çok daha az zaman aldığından, maliyete değer.

Ancak, genel olarak, AB olarak "aktif" iş parçacıklarının sayısının iki katını aştığınızda, OS, AB'nin zaman çizelgesi iş parçacıklarından daha fazla harcamaya başlar ve AB'ler, gerçek iş parçacığı çalıştırmak için harcadıklarından daha fazla zaman harcar programları. Ölçek ölçek ekonomilerinin noktası budur; bu noktada fazladan bir iş parçacığı ekleyecekseniz, çok iş parçacıklı bir algoritmanın çalışması daha uzun sürer.

Bu nedenle, genel olarak, programınızda bilgisayarınızda AB'leriniz olduğu kadar çok sayıda iş parçacığı tutmak istiyorsunuz, ancak beklemeyen veya uyumayan bu sayının iki katından daha fazlasına sahip olmaktan kaçınmak istiyorsunuz.


N iş parçacığı sayısı ve U birim sayısı ise, OP "N = U" kuralını sorguladı. Bir "U <= N <= 2 U" kuralına uyuyorsunuz. Biraz daha ileri gider ve "makul derecede küçük" bir sabit (programcı tarafından bilinir) c için "N <= c U" kabul edilebilir (eğer ölçütler makul performans gösteriyorsa). Konu sayısı potansiyel olarak sınırsız sayıda büyüyebilirse çok endişe ediyorum.
5gon12eder

1

Aşağıdakiler için bir iş parçacığı kullanmalısınız:

Meşgul olmanız gereken her işlemci.

Engellemediğiniz bir şekilde gerçekleştiremeyeceğiniz her I / O ile eşzamanlı olarak bekleyebilirsiniz. (Örneğin, yerel bir diskten okur.)

Özel bir iş parçacığı gerektiren her görev, örneğin engelleme olmayan arabirimi olmayan veya engelleme olmayan arabirimlerin uygun olmadığı bir kitaplığa çağrı. Bu, sistem saatini izleme, zamanlayıcıları ateşleme gibi görevleri içerir.

Sayfa hataları gibi beklenmedik engellemeye karşı korumak için birkaç ekstra.

Örneğin, kritik olmayan kodda, optimize etmeye değmeyecek beklenen engellemeye karşı korunmak için birkaç ekstra. (Örneğin, çok nadiren bir DNS isteği yapmanız gerekebiliyorsa, muhtemelen DNS isteklerini eşzamansız olarak yapmak için çaba harcamaya değmez. Sadece birkaç ekstra iş parçacığı oluşturun ve hayatınızı kolaylaştırın.)

"İşlemci başına bir iş parçacığı" kuralına uyarsanız, tüm kodunuz performans açısından kritik öneme sahiptir. Herhangi bir nedenle engellenen herhangi bir kod, işleminizin bu işlemciyi kullanamayacağı anlamına gelir. Bu, iyi bir sebep olmadan programlamayı çok daha zorlaştırır.


0

Tek bir program için çok çekirdekli \ çok işlemcili bir sistemin kullanılmasını sağlamak için işlemleri ve iş parçacıklarını oluşturabilirsiniz, bu durumda çekirdeklerden daha fazla iş parçacığı \ işlemine sahip olmaktan (en azından tek bir program için) fayda elde edemezsiniz.

Veya genellikle daha fazla yürütmeyi engelleyen bir etkinlik için anket yapan rutinleriniz olabilir. Daha sonra CPU'yu yoklama ile bağlayın, bunun yerine uygun olay uyanana kadar boşta kalacak bir iş parçacığı oluşturabilirsiniz. Bu yöntem, web sunucularında ve GUI olay kuyruklarında çok yaygın olarak kullanılır. Çoğu program, tüm iş parçacığı erişebilirsiniz merkezi veri deposu (hatta onun program yürütme kodu) bir tür olmasını istiyorum, bu yüzden süreçler üzerinde iş parçacığı kullanmak bu yüzden sanırım.


0

Bahsettiğiniz uygulamalar, nadiren aynı anda tüm bu onlarca iş parçacığını çalıştırıyor . Birçoğu sadece orada oturuyor çünkü bir iplik havuzundalar . Uygulama, iş parçacığı havuzundaki iş parçacıkları tarafından temizlenen bir kuyruğa çeşitli görevler gönderir.

Havuz neden bu kadar büyük? Genellikle ipler zorunda olduğundan beklemek vb bir iplik beklerken disk, ağ kullanıcı, diğer bazı iplik gibi diğer kaynaklar için tam işlemciyi kullanmak için, diğer konuları çalıştırmak için uygun bu. Havuz uygun boyutlandırma olsa da zor. Çok az iş parçacığı ve işlemci bir şey beklerken tam olarak kullanılmadığı için performansı kaybedersiniz. Çok fazla iş parçacığı ve aralarında geçiş nedeniyle performansı kaybedersiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.