Çekirdek başına optimum iplik sayısı


281

Diyelim ki 4 çekirdekli bir CPU'm var ve en kısa sürede bazı işlemler yapmak istiyorum. İşlem ideal olarak paralelleştirilebilir, bu yüzden sonsuz sayıda iş parçacığında parçalarını çalıştırabilirim ve her iş parçacığı aynı miktarda zaman alır.

4 çekirdeğim olduğundan, çekirdeklerden daha fazla iş parçacığı çalıştırarak herhangi bir hızlanma beklemiyorum, çünkü tek bir çekirdek yalnızca belirli bir anda tek bir iş parçacığı çalıştırabilir. Donanım hakkında fazla bir şey bilmiyorum, bu yüzden bu sadece bir tahmin.

Çekirdeklerden daha fazla iş parçacığında paralelleştirilebilir bir işlem gerçekleştirmenin bir faydası var mı? Başka bir deyişle, 4 iş parçacığı yerine 4000 iş parçacığı kullanarak çalıştırırsam, işlemim daha hızlı, daha yavaş veya yaklaşık aynı sürede biter mi?

Yanıtlar:


254

İş parçacıklarınız G / Ç, senkronizasyon vb. Yapmazsa ve çalışan başka bir şey yoksa, çekirdek başına 1 iş parçacığı size en iyi performansı verir. Ancak durum böyle değil. Daha fazla iş parçacığı eklemek genellikle yardımcı olur, ancak bir noktadan sonra bazı performans düşüşlerine neden olurlar.

Kısa bir süre önce, oldukça iyi bir yük altında Mono'da bir ASP.NET uygulaması çalıştıran 2 dört çekirdekli bir makinede performans testi yapıyordum. Minimum ve maksimum sayıda iş parçacığı ile oynadık ve sonuçta, belirli bir uygulamadaki söz konusu uygulama için en iyi işin 36 ila 40 iş parçacığı arasında bir yerde olduğunu öğrendik. Bu sınırların dışındaki her şey daha kötü performans gösterdi. Ders öğrenildi? Siz olsaydım, başvurunuz için doğru numarayı bulana kadar farklı sayıda iş parçacığıyla test ederdim.

Kesin olan bir şey var: 4k konuları daha uzun sürecek. Bu birçok bağlam anahtarı.


21
Bence Gonzalo'nun yanıtı iyi. Sadece denemeniz ve ölçmeniz gerektiğini ekliyorum. Programınız kendisinden veya benimkinden veya başka birinin programından farklı olacaktır ve yalnızca kendi programınızın davranışının ölçümleri sorularınızı doğru bir şekilde yanıtlayacaktır. Paralel (veya eşzamanlı) programların performansı, yalnızca ilk ilkelerden iyi sonuçların alınabileceği bir alan değildir.
Yüksek Performanslı Mark

5
+1, + cevap: çekirdeklerden çok daha fazla iş parçacığına sahip olmanın daha iyi performans sağlaması beni şaşırtıyor, ancak daha fazla iş parçacığının rakip iş parçacıklarına kıyasla daha fazla zaman payı anlamına gelmesi mantıklı. Uygulamamın performanstaki farklılıkları algılayabilmesi ve kendini en uygun iş parçacığına otomatik olarak ayarlayabilmesi güzel olurdu.
Juliet

12
Gerçek bir dünya senaryosunda sizi şaşırtmamalı. İş parçacıkları, disk erişimi, ağ vb. GÇ kaynaklarını beklemeyi engeller ve ayrıca diğer iş parçacıkları gibi GÇ olmayan kaynakların paylaşılan değişkenleri kullanarak bitmesini bekler. Gerçekte elde etmek istediğiniz şey, çekirdek başına en az bir iplik her zaman çalışabilecek şekilde minimum iplik sayısıdır.
patros

4
Çekirdek başına 1 iplik optimum değildir. Biraz daha fazla, tercihen iki katı olmalıdır, çünkü bu, bir iplik geçici olarak bloke edilirse başka bir ipliğin çalışmasına izin verecektir. Sadece hafızada bile. SMT / HT özelliğine sahip sistemleriniz (P4, I7, Sun Rock vb.) Varsa bu daha fazla önem taşır
Marco van de Voort

1
Bu yüzden cevabımdaki "Durum büyük olasılıkla böyle değil". Doğru numarayı bulmak uygulamaya ve üzerinde çalıştığı mimariye bağlıdır.
Gonzalo

129

@ Gonzalo'nun cevabına katılıyorum. G / Ç yapmayan bir işlemim var ve işte bulduğum şey:

resim açıklamasını buraya girin

Tüm iş parçacıklarının bir dizide ancak farklı aralıklarda çalıştığını (iki iş parçacığının aynı dizine erişmediğini) unutmayın, bu nedenle sonuçlar farklı dizilerde çalışmışsa farklılık gösterebilir.

1.86 makine, SSD'li bir macbook havasıdır. Diğer mac, normal HDD'ye sahip bir iMac (bence 7200 rpm). Windows makinesinde ayrıca 7200 rpm HDD bulunur.

Bu testte, optimal sayı makinedeki çekirdek sayısına eşitti.


14
Grafik için +1. Açıkçası çekirdek başına 1 iplik en iyisidir, ancak dört çekirdekli sistemin diğerlerinin yaptığı gibi daha yüksek iplik numaralarında (<100 zaten) görünmemesi ilginçtir.
Jim Garrison

46
Grafik için -1! Tamsayı değerli x-koordinatları ile düzgün eğriler? 1 2 3 ila 10 20 30 ila 50100 arasında vahşi bir sıçrama mı? Ve iyi ölçmek için 10 artı 2'nin katları olan y koordinatları. Bu Excel'in işi, değil mi?
Spacedman

5
@ Spacedman Evet öyle. Pürüzsüz eğriler çok daha güzel bir görünüme sahiptir IMHO. : D
Motasim

22
@PascalvKooten, Sorun güzel görünmemesi değil, ilk bakışta aldatıcı olması. Her şeyden önce, y ekseni 42'de başlar ve test edilen makineler arasındaki görünür farkı abartır. İkincisi, x ekseni değerlerinin garip ilerlemesi, 'zaman alınan' değerinin 'iş parçacığı sayısı' ile doğrusal olarak ölçeklenmediğini gösterir, bu özellikle mavi çizgi için geçerlidir. Bence diğerlerinin (kendim dahil) sahip olduğu sorun, verileri yanlış temsil etmesidir.
pauluss86

13
@ Spacedman Grafikteki eleştiri, son 24 saat içinde karşılaştığım en saçma şey. Grafik yardımcı olur. Çok. Dönemi. Daha iyi yapılabilir mi? Kimsenin umrunda değil. Ayrık yerine düzgün eğri? O senin problemin???? Sanırım hepiniz cevaplarına böyle bir grafik eklemeyeceksiniz çünkü iyi görünmesi için fazla zamana / enerjiye sahip değilsiniz. Demek istediğim bu.
tyrex

50

Bu sorunun oldukça eski olduğunu biliyorum, ancak 2009'dan beri işler gelişti.

Şu anda dikkate alınması gereken iki şey var: çekirdek sayısı ve her bir çekirdek içinde çalışabilecek iplik sayısı.

Intel işlemcilerde, iş parçacıklarının sayısı sadece 2 olan Hyperthreading tarafından tanımlanır (varsa). Ancak Hyperthreading, 2 iş parçacığı kullanılmasa bile yürütme sürenizi iki kat azaltır! (yani, iki işlem arasında paylaşılan 1 boru hattı - bu, daha fazla işleminiz olduğunda iyidir, aksi halde çok iyi değildir. Daha fazla çekirdek kesinlikle daha iyidir!)

Diğer işlemcilerde 2, 4 ve hatta 8 iş parçacığı olabilir. Dolayısıyla, her biri 8 iş parçacığını destekleyen 8 çekirdeğiniz varsa, bağlam değiştirme olmadan paralel çalışan 64 işleminiz olabilir.

Eğer kontrolünüz dışında her türlü bağlam için bağlam değiştirme yapacak standart bir işletim sistemi ile çalıştırırsanız "Bağlam değiştirme" kesinlikle doğru değildir. Ama ana fikir bu. Bazı işletim sistemleri işlemcileri ayırmanıza izin verir, böylece yalnızca uygulamanızın söz konusu işlemciye erişimi / kullanımı olur!

Kendi tecrübelerime göre, çok fazla G / Ç'niz varsa, birden çok iş parçacığı iyidir. Çok yoğun bellek yoğun çalışmanız varsa (kaynak 1, kaynak 2 oku, hızlı hesaplama, yazma) daha fazla iş parçacığına sahip olmak yardımcı olmaz. Yine, bu aynı anda ne kadar veri okuduğunuz / yazdığınıza bağlıdır (yani, SSE 4.2 kullanırsanız ve 256 bit değerlerini okursanız, adımlarındaki tüm iş parçacıklarını durdurur ... başka bir deyişle, 1 iş parçacığının uygulanması çok daha kolaydır ve Bu işlem ve bellek mimarinize bağlı olacaktır, bazı gelişmiş sunucular ayrı çekirdekler için ayrı bellek aralıklarını yönetir, böylece verilerinizin düzgün bir şekilde dosyalandığını varsayarak ayrı iş parçacıkları daha hızlı olur ... bu nedenle, bazılarında mimariler, 4 işlem 4 iş parçacığı ile 1 işlemden daha hızlı çalışacaktır.)


4
Muhtemelen başkaları da var, ama bildiğim IBM'in POWER işlemcisi. İşlemci başına 4 veya 8 iş parçacığı olan sistemler vardı. Şimdi daha fazla çekirdekte krank yapabilirler, bunun yerine çekirdek başına 2 iş parçacığı sunarlar ...
Alexis Wilke

Bu eski, ancak Intel i5, i7'nin çoğunda çok iş parçacıklı cpu var, örneğin i7 cpu'nun genellikle 4 çekirdeği var, ancak 8 iş parçacığı var.
Edgar.

4
İşlemcilerin iş parçacığı yoktur. Fiziksel ve mantıksal çekirdekleri var. Hiper iş parçacığı ile, tek bir fiziksel çekirdek iki mantıksal çekirdek olarak işlev görür. İş parçacığı olan işlemcilerin gerçek bir şey olduğu konusunda ısrar eden bir teknolojim vardı, bu yüzden bir işlemcinin beyaz tahtasına, iş parçacığının iş parçacığından çıkmasıyla bir resim çizdim.

@TechnikEmpire Bu intel.com/content/www/us/en/processors/core/… adresine bir göz atın , belki o zaman intel ile iletişime geçebilir ve bunları konulara da çekebilirsiniz.
g7k

24

Gerçek performans, her bir iş parçacığının ne kadar gönüllü vereceğine bağlı olacaktır. Örneğin, iş parçacıkları HİÇBİR G / Ç yapmıyorsa ve hiçbir sistem hizmeti kullanmıyorsa (yani% 100 cpu'ya bağlıysa) çekirdek başına 1 iş parçacığı en uygunudur. İş parçacıkları, beklemenizi gerektiren bir şey yaparsa, en uygun iş parçacığı sayısını belirlemek için deneme yapmanız gerekir. 4000 iş parçacığı önemli zamanlama yüküne neden olur, bu da muhtemelen optimal değildir.


21

Cevap, programda kullanılan algoritmaların karmaşıklığına bağlıdır. İki rasgele sayıda 'n' ve 'm' için Tn ve Tm işlem sürelerinin iki ölçümünü yaparak en uygun iş parçacığı sayısını hesaplamak için bir yöntem buldum. Doğrusal algoritmalar için, en uygun iş parçacığı sayısı N = sqrt ((m n (Tm * (n-1) - Tn * (m-1))) / (n Tn-m Tm)) olacaktır.

Çeşitli algoritmalar için en uygun sayı hesaplamaları ile ilgili makalemi okuyun: pavelkazenin.wordpress.com


4
Neden indirilmiyor? Üzgünüm ama bu soruya verilecek en iyi cevap bu. gonzalo sorunun cesur kısmını ve pkazen başlığı ele alıyor. Her iki cevap da çok faydalıdır, ancak pkazen cevabı önemlidir çünkü iplik sayısına yaklaşık olarak sistematik bir yöntemimiz vardır. Linea algoritmalarının formülünü bile veriyor.
tobiak777

1
Oy vermedim ama eğer yapsaydım, en uygun iş parçacığının neden algoritmanın karmaşıklığı ile ilgili olabileceği veya nasıl olabileceğine dair gerçek bir açıklama olmaması temelinde, bağlı makalenin tamamını okuyarak kaydedin. uzun bir okuma (makalenin karmaşıklığı nedeniyle). Bunun ötesinde, makalenin bazı yönleri benim için net değil, en önemlisi deneysel sonuçların teoriyi nasıl doğruladığı.
18'de

Ayrıca, bu hesaplamanın sonsuz sayıda CPU çekirdeğine sahip olduğunuzu varsaydığını düşünüyorum. Bu kesinlikle değerli bir bilgi olsa da, soru az sayıda çekirdeğe sahip gerçek makinelere atıfta bulunuyor.
Navneeth

9

Buraya başka bir bakış açısı ekleyeceğimi düşündüm. Cevap, sorunun zayıf ölçeklendirme mi yoksa güçlü ölçeklendirme mi kabul ettiğine bağlıdır.

Gönderen Vikipedi :

Zayıf ölçeklendirme: İşlemci başına sabit bir sorun boyutu için çözüm süresinin işlemci sayısına göre nasıl değiştiği.

Güçlü ölçeklendirme: sabit toplam sorun boyutu için çözüm süresinin işlemci sayısına göre nasıl değiştiği.

Soru zayıf ölçeklendirme varsa, @ Gonzalo'nun cevabı yeterlidir. Ancak, soru güçlü ölçeklendirme varsayıyorsa, eklenecek daha fazla şey var. Güçlü ölçeklendirmede sabit bir iş yükü boyutu olduğunu varsayıyorsunuz, böylece iş parçacığı sayısını artırırsanız, her iş parçacığının üzerinde çalışması gereken verilerin boyutu azalır. Modern CPU'larda bellek erişimi pahalıdır ve verileri önbellekte tutarak yerelliğin korunması tercih edilir. Bu nedenle, her bir iş parçacığının veri kümesi her bir çekirdeğin önbelleğine sığdığında olası en uygun iş parçacığı sayısı bulunabilir (sistemin L1 / L2 / L3 önbellek (ler) i olup olmadığını tartışmanın ayrıntılarına girmiyorum).

Bu, iş parçacığı sayısı çekirdek sayısını aşsa bile geçerlidir. Örneğin, programda 4 çekirdekli bir makinede yürütülecek 8 rasgele birim (veya AU) çalışma olduğunu varsayalım.

Dava 1: Her bir iş parçacığının 2AU'yu tamamlaması gereken dört iş parçacığıyla çalıştırın. Her iş parçacığının tamamlanması 10 saniye sürer ( çok fazla önbellek özlüyor ). Dört çekirdekli toplam süre 10 saniye olacaktır (10s * 4 diş / 4 çekirdek).

Durum 2: Her bir iş parçacığının 1AU'yu tamamlaması gereken sekiz iş parçacığıyla çalıştırın. Her iş parçacığı yalnızca 2s sürer (önbellek hatalarının azalması nedeniyle 5s yerine ). Dört çekirdek ile toplam süre 4 s olacaktır (2s * 8 diş / 4 çekirdek).

Sorunu basitleştirdim ve diğer yanıtlarda (örneğin, bağlam anahtarları) belirtilen genel giderleri görmezden geldim, ancak veri boyutuna bağlı olarak mevcut çekirdek sayısından daha fazla sayıda iş parçacığına sahip olmanın yararlı olabileceğini umuyoruz. ilgileniyor.


7

Bir seferde 4000 iplik oldukça yüksektir.

Cevap evet ve hayır. Her iş parçacığında çok fazla engelleme G / Ç yapıyorsanız, evet, mantıksal çekirdek başına muhtemelen 3 veya 4 iş parçacığına kadar önemli hızlandırmalar gösterebilirsiniz.

Ancak çok fazla engelleme yapmıyorsanız, diş çekme ile ekstra yük sadece yavaşlatacaktır. Bu yüzden bir profil oluşturucu kullanın ve darboğazların muhtemelen her paralel parçada nerede olduğunu görün. Ağır hesaplamalar yapıyorsanız, CPU başına 1'den fazla iş parçacığı yardımcı olmaz. Çok fazla bellek aktarımı yapıyorsanız, bu da yardımcı olmaz. Disk erişimi veya internet erişimi gibi çok fazla G / Ç yapıyorsanız, evet birden çok iş parçacığı belirli bir dereceye kadar yardımcı olur veya en azından uygulamayı daha duyarlı hale getirir.


7

Benchmark.

Bir uygulama için iş parçacığı sayısını artırmaya başladım, 1'den başladım ve sonra 100 gibi bir şeye geçirdim, her iş parçacığı sayısı için üç beş deneme çalıştırdım ve iş parçacığı sayısına karşı işlem hızının bir grafiğini oluşturdum .

Dört iş parçacığının en uygun durumda olması gerekir, bundan sonra çalışma zamanında hafif artışlar olur, ancak olmayabilir. Uygulamanız bant genişliği sınırlı olabilir, yani belleğe yüklediğiniz veri kümesi çok büyük, 2 iş parçacığı en iyi olacak şekilde çok sayıda önbellek özlüyor, vb.

Test edene kadar bilemezsin.


3

Makinenizde kaç tane iş parçacığı çalıştırabileceğinizi, makinenizdeki işlem sayısını döndüren htop veya ps komutunu çalıştırarak bulabilirsiniz.

'Ps' komutu hakkında man sayfasını kullanabilirsiniz.

man ps

Tüm kullanıcıların işlem sayısını hesaplamak istiyorsanız, aşağıdaki komutlardan birini kullanabilirsiniz:

  1. ps -aux| wc -l
  2. ps -eLf | wc -l

Bir kullanıcı işleminin sayısını hesaplama:

  1. ps --User root | wc -l

Ayrıca, "htop" kullanabilirsiniz [Referans] :

Ubuntu veya Debian'a kurulum:

sudo apt-get install htop

Redhat veya CentOS'a kurulum:

yum install htop
dnf install htop      [On Fedora 22+ releases]

Htop'u kaynak kodundan derlemek isterseniz, burada bulabilirsiniz .


2

İdeal olan, çekirdeklerin hiçbiri bloke olmayacağı sürece çekirdek başına 1 ipliktir.

Bunun doğru olmayabileceği bir durum: çekirdek üzerinde çalışan başka iş parçacıkları vardır, bu durumda daha fazla iş parçacığı programınıza yürütme süresinin daha büyük bir bölümünü verebilir.


Uygulamanız çalışırken kullanıcıların arka plan işlemlerinin bok gibi çalışmasını isteyip istemediğinize bağlıdır. Bu nedenle, her bir iş parçacığı için gerçek zamanlı bir öncelik belirleyebilir ve maksimum güç miktarını elde edebilirsiniz. Ancak kullanıcılar çoklu görevleri sever.
Earlz

2
İdeal olarak paralelleştirilebilir büyülü bir uygulama ile uğraşıyoruz. Eğer böyle bir şey yaratsaydım, CPU'yu istediğim kadar domine etme hakkım olurdu.
patros

2

Çekirdek başına bir çok iş parçacığının ("iş parçacığı havuzu") bir örneği, Linux veya Windows'ta bir web sunucusu uygulamaktır.

Linux'ta soketler sorgulandığından, bir çok iş parçacığı birinin doğru soketi doğru zamanda çağırma olasılığını artırabilir - ancak genel işlem maliyeti çok yüksek olacaktır.

Windows'ta sunucu, uygulama olayını yönlendiren G / Ç Tamamlama Bağlantı Noktaları - IOCP'ler kullanılarak uygulanacaktır: Bir G / Ç işlemi tamamlarsa işletim sistemi tamamlandığında, işlemek için hazır bir iş parçacığı başlatılır. İşlem tamamlandığında (genellikle bir istek yanıt çiftinde olduğu gibi başka bir G / Ç işlemi ile), iş parçacığı sonraki tamamlamayı beklemek için IOCP bağlantı noktasına (kuyruk) geri döner.

Hiçbir G / Ç tamamlanmadıysa, yapılacak işlem yoktur ve hiçbir iş parçacığı başlatılmaz.

Aslında, Microsoft, IOCP uygulamalarında çekirdek başına birden fazla iş parçacığı önermemektedir. IOCP mekanizmasına herhangi bir G / Ç eklenebilir. Gerekirse, IOC'ler başvuru tarafından da gönderilebilir.


Hangi Linux hakkında konuştuğunuzu bilmiyorum, ancak bir bağlantı kurulana kadar bloklarım. Select () ve FD_SET () ve benzeri işlevler / makrolar hakkında birkaç şey okumanızı öneririm.
Alexis Wilke

Tamam, hemen dönen bir asenkron form yok mu?
Olof Forshell

Select () man sayfasından:timeout is an upper bound on the amount of time elapsed before select() returns. If both fields of the timeval structure are zero, then select() returns immediately. (This is useful for polling.) If timeout is NULL (no timeout), select() can block indefinitely.
Alexis Wilke

0

hesaplama ve hafızaya bağlı bakış açısıyla konuşmak (bilimsel hesaplama) 4000 iş parçacığı uygulamayı gerçekten yavaşlatacaktır. Sorunun bir kısmı, bağlam değiştirme ve büyük olasılıkla çok zayıf bellek konumunun çok yüksek bir yüküdür.

Ama aynı zamanda mimarinize de bağlıdır. Duyduğum yerden Niagara işlemcileri, bir tür gelişmiş boru hattı tekniği kullanarak tek bir çekirdek üzerinde birden fazla iş parçacığını işleyebildiğini varsayalım. Ancak bu işlemcilerle ilgili hiçbir deneyimim yok.


0

Umarım bu mantıklıdır, CPU ve Bellek kullanımını kontrol edin ve bir miktar eşik değeri koyun. Eşik değeri aşılırsa, başka bir iş parçacığı oluşturmaya izin vermeyin ...

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.