Çok iş parçacığı: Çekirdeklerden daha fazla iş parçacığının anlamı nedir?


142

Çok çekirdekli bir bilgisayarın amacının aynı anda birden çok iş parçacığı çalıştırabileceğini düşündüm. Bu durumda, dört çekirdekli bir makineniz varsa, aynı anda 4'ten fazla iş parçacığının çalışmasının anlamı nedir? Sadece birbirlerinden zaman (CPU Kaynakları) çalmıyorlar mı?


52
Biz bu tür soruları zevk, onlar verilen bir şey, çok temel sorgulamak .. geliyor geliyor ..
Srinivas Reddy Thatiparthy

6
Firefox, MS Word, Winamp, Eclipse ve en son ne zaman dört çekirdekli makinenizde aynı anda çalışan bir indirme yöneticisi (dörtten fazla program / süreç) vardı? Ayrıca, tek bir uygulama bazen dörtten fazla iş parçacığı oluşturabilir - buna ne dersiniz?
Amarghosh

1
Çalmak her zaman kötü değildir. Zamanı çalması gereken önemli görevler için daha yüksek önceliğe sahip bir iş parçacığınız olabilir.
kichik

1
@Amarghosh Sanırım soru buydu, tek bir uygulama neden herhangi bir performans avantajı getirmiyorsa çekirdeklerden daha fazla iş parçacığı oluşturmak isteyebilir. Ve dörtten fazla programa sahip örneğiniz burada pek alakalı değil. Doğru belirttiğiniz gibi, bunlar süreçlerdir. İşletim sistemi çoklu görev özelliğinin (işlem çoğullama) bir işlemdeki iş parçacıklarıyla çok az ilgisi vardır.
Aleksandr Ivannikov

Yanıtlar:


81

Cevap, paralellik olan iş parçacıklarının amacı etrafında dönmektedir: aynı anda birkaç ayrı yürütme çizgisi çalıştırmak. 'İdeal' bir sistemde, çekirdek başına bir iş parçacığı yürütürsünüz: kesinti yok. Gerçekte durum böyle değil. Dört çekirdeğiniz ve dört iş parçacığınız olsa bile, işleminiz ve iş parçacıkları diğer işlemler ve iş parçacıkları için sürekli olarak kapatılacaktır. Herhangi bir modern işletim sistemi kullanıyorsanız, her işlemin en az bir iş parçacığı vardır ve birçoğunun daha fazlası vardır. Tüm bu işlemler aynı anda çalışıyor. Muhtemelen şu anda makinenizde çalışan yüzlerce iplik var. Bir iş parçacığının 'çalınan' zaman olmadan işleyeceği bir durum elde edemezsiniz. (Peki, gerçek zamanlı çalışıyorsa, gerçek zamanlı bir işletim sistemi kullanıyorsanız veya Windows'ta bile gerçek zamanlı bir iş parçacığı önceliği kullanın. Ancak bu nadirdir.)

Arka plan olarak, cevap: Evet, gerçek bir dört çekirdekli makinede dörtten fazla iş parçacığı size 'birbirlerinden zaman çalma' durumu verebilir, ancak her bir iş parçacığının% 100 CPU'ya ihtiyacı varsa . Bir iş parçacığı% 100 çalışmıyorsa (UI iş parçacığı olmayabilir veya az miktarda iş yapan veya başka bir şey bekleyen bir iş parçacığı gibi), zamanlanmış başka bir iş parçacığı aslında iyi bir durumdur.

Aslında bundan daha karmaşık:

  • Hepsi aynı anda yapılması gereken beş iş parçanız varsa ne olur? Hepsini birden çalıştırmak, dördünü çalıştırmak ve daha sonra beşincisini çalıştırmak daha mantıklı.

  • Bir iş parçacığının gerçekten% 100 CPU'ya ihtiyacı nadirdir. Örneğin, disk veya ağ G / Ç kullandığı anda, yararlı bir şey yapmayı beklemek zaman harcayabilir. Bu çok yaygın bir durum.

  • Çalıştırılması gereken bir işiniz varsa, ortak bir mekanizma threadpool kullanmaktır. Çekirdeklerle aynı sayıda iş parçacığına sahip olmak mantıklı görünebilir, ancak .Net iş parçacığı işlemci başına 250 adede kadar iş parçacığına sahiptir . Neden bunu yaptıkları emin değilim, ama benim tahminim iş parçacıkları üzerinde çalıştırmak için verilen görevlerin boyutu ile ilgilidir.

Yani: çalma zamanı kötü bir şey değil (ve gerçekten hırsızlık da değil, ya da sistemin çalışması gerekiyordu.) Çok iş parçacıklı programlarınızı, iş parçacığının yapacağı iş türüne göre yazın. -ciltli. Profil oluşturma ve ölçüme göre ihtiyacınız olan diş sayısını belirleyin. İş parçacıkları yerine görevler veya işler açısından düşünmeyi daha yararlı bulabilirsiniz: iş nesnelerini yazın ve çalıştırılacak bir havuza verin. Son olarak, programınız gerçekten performans açısından kritik değilse, çok fazla endişelenmeyin :)


16
+1 için "yalnızca her bir iş parçacığında% 100 CPU gerekiyorsa". Yaptığımı fark etmediğim varsayım buydu.
Nick Heiner

1
Harika bir soru için harika bir cevap. Teşekkür ederim!
Edgecase

53

Bir iş parçacığının var olması her zaman etkin olarak çalıştığı anlamına gelmez. Birçok iş parçacığı uygulaması, bir şeyler yapma zamanı gelene kadar uyuyacak bazı iş parçacıklarını içerir - örneğin, kullanıcı girişi, iş parçacıklarını uyandırmak, biraz işlem yapmak ve uykuya geri dönmek için tetikler.

Esasen, iş parçacıkları, başka bir görevin ilerlemesinin farkında olmanıza gerek kalmadan, birbirinden bağımsız olarak çalışabilen bireysel görevlerdir. Aynı anda koşma yeteneğinizden daha fazlasına sahip olmak mümkündür; bazen birbiri ardına sıra beklemek zorunda kalsalar da kolaylık sağlamak için hala yararlıdırlar.


11
İyi dedi. 'CPU başına bir iş parçacığı' bağımsız değişkeni yalnızca CPU'ya bağlı kod için geçerlidir. Zaman uyumsuz programlama iş parçacığı kullanmanın başka bir nedenidir.
Joshua Davis

26

Mesele şu ki, iş parçacığı sayısı çekirdek sayısını aştığında gerçek bir hızlanma elde etmemesine rağmen, birbirine bağımlı olması gerekmeyen mantık parçalarını ayırmak için iş parçacıklarını kullanabilirsiniz.

Orta derecede karmaşık bir uygulamada bile, tek bir iş parçacığı kullanarak her şeyi hızlı bir şekilde yapmaya çalışın, kodunuzun 'akışını' karma yapar. Tek iplik zamanının çoğunu bunu sorgulayarak geçirir, bunu kontrol eder, şartlı olarak rutinleri gerektiği gibi çağırır ve bir minutia tacizinden başka bir şey görmek zorlaşır.

Bunu, herhangi bir iş parçacığına bakarak iş parçacığının ne yaptığını görebilmeniz için iş parçacıklarını görevlere ayırabileceğiniz durumla karşılaştırın. Örneğin, bir iş parçacığı bir soketten gelen girdide beklemeyi engelleyebilir, akışı iletilere ayrıştırabilir, iletilere filtre uygulayabilir ve geçerli bir ileti geldiğinde diğer iş parçacığına iletebilir. Çalışan iş parçacığı, bir dizi başka kaynaktan gelen girdiler üzerinde çalışabilir. Bunların her birinin kodu, başka bir şey olmadığını açıkça kontrol etmek zorunda kalmadan, temiz, amaçlı bir akış gösterecektir.

İşi bu şekilde bölümlere ayırmak, uygulamanızın cpu ile bir sonraki adımda ne yapacağını planlamak için işletim sistemine güvenmesine izin verir;


1
Bu ilginç bir düşünce ... Her zaman bir uygulamanın çoklu iş parçacığının net bir karmaşıklık eklentisi olduğunu duydum, ancak söylediğiniz şey mantıklı.
Nick Heiner

Bir uygulamanın çok iş parçacığına alınması, endişeleri yeterince ayrılmazsa karmaşıklık katar. Endişelerin (ve dolayısıyla paylaşılan devletin) minimum örtüşmesiyle tasarlanırsa, karmaşıklık sorunlarında net bir tasarruftur.
SADECE benim doğru GÖRÜŞÜM

Kontrol akışının programları yazdığınız düzeyde daha net olması için tek iş parçacıklı uygulamaları yapılandırmanın yolları vardır. OTOH, iş parçacıklarınızı yalnızca birbirlerine ileti iletecek şekilde (paylaşılan kaynaklara sahip olmak yerine) yapılandırabiliyorsanız, neler olup bittiğini anlamak ve her şeyin çalışmasını sağlamak oldukça basittir.
Donal Fellows

1
Bununla birlikte, iş parçacıklarının kullanılmasının sadece belirli bir noktaya kadar olan şeyleri basitleştirebileceğine dikkat çekmelidir. Çoğu zaman, iki iş parçacığının, karmaşıklığın maça geri döndüğü, doğru bir şekilde yapılması gereken işi yapması için girişimde bulunulur. Bunun belirtileri, istenen bazı sonuçları koordine etmek için aşırı iletişim ve senkronizasyon gereksinimleridir.
JustJeff

15

Bir iş parçacığı bir kaynak bekliyorsa (RAM'den bir yazmacıya bir değer yüklemek, disk G / Ç, ağ erişimi, yeni bir işlem başlatmak, bir veritabanını sorgulamak veya kullanıcı girişini beklemek gibi), işlemci bir farklı bir iş parçacığı ve kaynak kullanılabilir olduğunda ilk iş parçacığına dönün. Bu, CPU boşta durma süresini azaltır, çünkü CPU boşta oturmak yerine milyonlarca işlem gerçekleştirebilir.

Sabit diskten veri okuması gereken bir iş parçacığı düşünün. 2014 yılında, tipik bir işlemci çekirdeği 2,5 GHz hızında çalışır ve döngü başına 4 komut yürütebilir. 0,4 ns döngü süresiyle, işlemci nanosaniye başına 10 komut yürütebilir. Tipik mekanik sabit sürücü arama süreleri yaklaşık 10 milisaniyedir, işlemci sabit sürücüden bir değer okumak için gereken sürede 100 milyon talimat yürütebilir. Küçük bir önbelleğe (4 MB arabellek) sahip sabit sürücüler ve birkaç GB depolama alanına sahip hibrit sürücüler ile önemli performans iyileştirmeleri olabilir, çünkü hibrit bölümden sıralı okumalar veya okumalar için veri gecikmesi birkaç kat daha hızlı olabilir.

İşlemci çekirdeği, iş parçacıkları arasında geçiş yapabilir (bir iş parçacığını duraklatma ve sürdürme maliyeti yaklaşık 100 saat döngüdür), ilk iş parçacığı yüksek gecikme girdisi (kayıtlar (1 saat) ve RAM'den (5 nanosaniye) daha pahalı bir şey) bekler. disk G / Ç, ağ erişimi (250 ms gecikme), CD veya yavaş bir veriyolundan veri okuma veya veritabanı çağrısı. Çekirdeklerden daha fazla iş parçacığına sahip olmak, yüksek gecikmeli görevler çözülürken faydalı işlerin yapılabileceği anlamına gelir.

CPU, her bir iş parçacığına öncelik veren ve bir iş parçacığının uyumasına izin veren bir iş parçacığı zamanlayıcısına sahiptir ve daha sonra önceden belirlenmiş bir süreden sonra devam eder. Her iş parçacığının tekrar uykuya alınmadan önce sadece 100 yönerge yürütmesi durumunda ortaya çıkacak olan döküntüyü azaltmak iş parçacığı zamanlayıcısının görevidir. Anahtarlama dişlerinin ek yükü, işlemci çekirdeğinin toplam faydalı verimini azaltacaktır.

Bu nedenle, sorununuzu makul sayıda iş parçacığına bölmek isteyebilirsiniz. Matris çarpımı gerçekleştirmek için kod yazıyorsanız, çıkış matrisinde hücre başına bir iş parçacığı oluşturmak aşırı olabilirken, çıkış matrisindeki her satırda veya her n satırda iş parçacığı oluşturma, duraklatma ve devam ettirme genel maliyetini düşürebilir.

Şube tahmini bu yüzden önemlidir. RAM'den bir değer yüklemeyi gerektiren bir if ifadeniz varsa, ancak if ve else ifadelerinin gövdesi, kayıtlara önceden yüklenmiş değerleri kullanıyorsa, koşul değerlendirilmeden önce işlemci bir veya iki dalı yürütebilir. Koşul geri döndüğünde, işlemci ilgili dalın sonucunu uygular ve diğerini atar. Burada potansiyel olarak işe yaramaz bir iş yapmak muhtemelen farklı bir iş parçacığına geçmekten daha iyidir, bu da çöpe neden olabilir.

Yüksek saat hızındaki tek çekirdekli işlemcilerden çok çekirdekli işlemcilere geçtikçe, çip tasarımı, kalıp başına daha fazla çekirdeği sıkıştırmaya, çekirdekler arasındaki çip üzerinde kaynak paylaşımını iyileştirmeye, daha iyi dal tahmin algoritmalarına, daha iyi iplik değiştirme yüküne, ve daha iyi iplik programlaması.


Aynı şey tek bir iş parçacığı ve bir kuyrukla da yapılabilir: \ 2-4 çekirdeğinde 80 iş parçacığına sahip olmanın gerçekten herhangi bir yararı var mı, sadece geldikleri anda sıradan görevleri yiyen 2-4 çekirdeğe sahip olmak ve yapacak bir şeyleri yok mu?
Dmitry

8

Yukarıdaki cevapların çoğu performans ve eşzamanlı çalışma hakkında konuşmaktadır. Buna farklı bir açıdan yaklaşacağım.

Basit bir terminal öykünme programı örneğini ele alalım. Aşağıdaki şeyleri yapmak zorundasınız:

  • uzaktaki sistemden gelen karakterleri izleyin ve görüntüleyin
  • klavyeden gelen şeyleri izleyin ve uzak sisteme gönderin

(Gerçek terminal emülatörleri, yazdığınız şeylerin ekrana da yansıtılması da dahil olmak üzere daha fazlasını yapar, ancak şimdilik bunu geçeceğiz.)

Şimdi, aşağıdaki sahte kodlara göre uzaktan kumandadan okuma döngüsü basit:

while get-character-from-remote:
    print-to-screen character

Klavyeyi izleme ve gönderme döngüsü de basittir:

while get-character-from-keyboard:
    send-to-remote character

Ancak sorun, bunu aynı anda yapmanız gerektiğidir. Eğer iş parçacığına sahip değilseniz, kod şimdi daha fazla görünmelidir:

loop:
    check-for-remote-character
    if remote-character-is-ready:
        print-to-screen character
    check-for-keyboard-entry
    if keyboard-is-ready:
        send-to-remote character

İletişimin gerçek dünyadaki karmaşıklığını hesaba katmayan kasıtlı olarak basitleştirilmiş bu örnekte bile mantık oldukça gizlidir. Bununla birlikte, diş açma ile, tek bir çekirdek üzerinde bile, iki sahte kod döngüsü mantıklarını birbirine bağlamadan bağımsız olarak var olabilir. Her iki iş parçacığı çoğunlukla G / Ç'ye bağlı olacağından, kesin olarak konuşursak, entegre döngüden daha fazla CPU kaynağı israf etseler bile CPU'ya ağır bir yük yüklemezler.

Şimdi elbette gerçek dünya kullanımı yukarıdakilerden daha karmaşık. Ancak, uygulamaya daha fazla endişe ekledikçe, tümleşik döngünün karmaşıklığı katlanarak artar. Mantık gittikçe parçalanır ve işleri yönetilebilir hale getirmek için devlet makineleri, yardımcı programlar ve diğerleri gibi teknikleri kullanmaya başlamanız gerekir. Yönetilebilir, ancak okunamaz. Diş açma kodu daha okunaklı tutar.

Peki neden ipliği kullanmıyorsunuz?

Görevleriniz I / O-bağlı yerine CPU-bağlıysa, iş parçacığı gerçekte sisteminizi yavaşlatır. Performans düşecektir. Pek çok durumda. (Çok fazla CPU'ya bağlı iş parçacığı bırakırsanız "Thrashing" yaygın bir sorundur. Etkin iş parçacıklarını değiştirmek için iş parçacıklarının içeriğini çalıştırdığınızdan daha fazla zaman harcarsınız.) Ayrıca, yukarıdaki mantığın nedenlerinden biri de o kadar basit ki, kasten basit (ve gerçekçi olmayan) bir örnek seçtim. Ekrana yazılanları yankılamak istiyorsanız, paylaşılan kaynakların kilitlenmesini tanıtırken yeni bir acı dünyasına sahipsiniz. Tek bir paylaşılan kaynakla bu çok sorun değil, ancak daha fazla kaynağınız olduğu için daha büyük ve daha büyük bir sorun olmaya başlıyor.

Sonuçta, iplik geçirme birçok şeyle ilgilidir. Örneğin, bazılarının söylediği gibi, G / Ç'ye bağlı işlemleri daha duyarlı (genel olarak daha az verimli olsa bile) yapmakla ilgilidir. Aynı zamanda mantığı daha kolay takip etmekle ilgilidir (ancak yalnızca paylaşılan durumu en aza indirirseniz). Bu bir çok şey hakkında ve avantajlarının dezavantajlarını duruma göre ağır basmayacağına karar vermelisiniz.


6

Donanımınıza bağlı olarak hesaplamaları hızlandırmak için kesinlikle iş parçacıkları kullanabilmenize rağmen, ana kullanımlarından biri, kullanıcı dostu nedenlerden ötürü bir kerede birden fazla şey yapmaktır.

Örneğin, arka planda bazı işlemler yapmanız ve ayrıca kullanıcı arayüzü girişine yanıt vermeniz gerekiyorsa, iş parçacıklarını kullanabilirsiniz. İş parçacıkları olmadan, her ağır işlemde kullanıcı arabirimi kilitlenir.

Ayrıca bu ilgili soruya bakın: İpliklerin pratik kullanımları


Kullanıcı arabirimi yönetimi, IO'ya bağlı görevin klasik bir örneğidir. Hem işleme hem de GÇ görevlerini yapan tek bir CPU çekirdeğine sahip olmak iyi değildir.
Donal Fellows

6

@ Kyoryu'nun ideal sayının CPU başına bir iş parçacığı olduğu iddiasına kesinlikle katılmıyorum.

Bunu şu şekilde düşünün: Neden çok işlemcili işletim sistemlerimiz var? Bilgisayar geçmişinin çoğunda, neredeyse tüm bilgisayarlarda bir CPU bulunur. Ancak 1960'lı yıllardan itibaren, tüm "gerçek" bilgisayarlarda çoklu işlem (çoklu görev olarak da bilinir) işletim sistemleri vardı.

Birden çok program çalıştırırsınız, böylece diğerleri IO gibi şeyler için engellenirken çalıştırılabilir.

NT'den önceki Windows sürümlerinin çoklu görev olup olmadığı konusundaki argümanları bir kenara bırakalım. O zamandan beri, her gerçek işletim sisteminin çoklu görevi vardı. Bazıları bunu kullanıcılara maruz bırakmıyor, ancak yine de orada, cep telefonu radyosunu dinlemek, GPS çipiyle konuşmak, fare girişini kabul etmek vb.

Konular sadece biraz daha verimli olan görevlerdir. Görev, süreç ve iş parçacığı arasında temel bir fark yoktur.

Bir CPU boşa harcanan korkunç bir şeydir, bu yüzden yapabildiğiniz zaman kullanmaya hazır birçok şey bulundurun.

Çoğu prosedürel dil, C, C ++, Java vb.Ile, uygun iş parçacığı güvenli kod yazmanın çok iş olduğunu kabul edeceğim. Bugün piyasada bulunan 6 çekirdekli CPU ve çok uzak olmayan 16 çekirdekli CPU ile, çoklu iş parçacığı gittikçe daha kritik bir gereklilik olduğundan, halkın bu eski dillerden uzaklaşmasını bekliyorum.

@Kyoryu ile anlaşmazlık sadece IMHO, gerisi gerçektir.


5
İşlemciye bağlı çok sayıda iş parçacığınız varsa, ideal sayı CPU başına birdir (veya belki de bir tane daha az, tüm G / Ç'yi ve işletim sistemini ve tüm bu şeyleri yönetmek için bir tane bırakmak). Eğer var ise IO bağlı konuları, tek bir CPU üzerinde oldukça fazla yığabilirsiniz. Farklı uygulamaların işlemci ve GÇ'ye bağlı görevlerin farklı karışımları vardır; bu tamamen doğal, ama neden evrensel beyanlara dikkat etmelisiniz.
Donal Fellows

1
Tabii ki, iş parçacıkları ve işlemler arasındaki en önemli fark, Windows'ta çatal () olmamasıdır, bu nedenle işlem oluşturma gerçekten pahalıdır ve iş parçacıklarının aşırı kullanımına yol açar.
ninjalj

Protein katlanması, SETI, vb. Dışında, işlemin çok uzun süre bağlı olduğu pratik kullanıcı görevleri yoktur. Her zaman kullanıcıdan bilgi almak, diskle konuşmak, DBMS ile konuşmak vb. İçin bir ihtiyaç vardır. Evet, çatal () masrafı Cutler'ın DEC'deki diğerlerinin bildiği NT ile lanetlediği birçok şeyden biridir.
fishtoprecords

5

Rastgele sayıda istek sunması gereken bir Web sunucusu düşünün. İstekleri paralel olarak sunmanız gerekir, aksi takdirde her yeni isteğin diğer tüm isteklerin tamamlanmasını beklemesi gerekir (yanıtı Internet üzerinden gönderme dahil). Bu durumda, çoğu web sunucusu genellikle hizmet ettikleri istek sayısından daha az çekirdeğe sahiptir.

Aynı zamanda sunucunun geliştiricisi için de kolaylık sağlar: Sadece bir istek sunan bir iş parçacığı programı yazmanız yeterlidir, birden çok isteği saklamak, onlara hizmet verdiğiniz sipariş vb.


2
Diş çekmeyi destekleyen ancak çoğullama kapasitesi olmayan bir işletim sistemi için yazılım mı yazıyorsunuz? Bence web sunucusu muhtemelen kötü bir örnek çünkü bu durumda çoğullama io neredeyse her zaman çekirdek daha fazla iş parçacığı yumurtlama daha verimli olacaktır.
Jason Coco

3

Birçok iş parçacığı uykuda olacak, kullanıcı girişi, G / Ç ve diğer olayları bekleyecektir.


Kesinlikle. Windows'ta Görev Yöneticisi'ni veya gerçek işletim sisteminde TOP'u kullanın ve kaç görev / işlemin alseep olduğunu görün. Her zaman% 90 veya daha fazla.
fishtoprecords

2

Konular, UI uygulamalarında yanıt verme konusunda yardımcı olabilir. Ayrıca, çekirdeklerinizden daha fazla iş almak için dişleri kullanabilirsiniz. Örneğin, tek bir çekirdekte, bir iş parçacığının IO ve başka bir iş parçacığının bir hesaplama yapmasını sağlayabilirsiniz. Tek dişli olsaydı, çekirdek aslında ES'nin tamamlanmasını bekleyen boşta olabilir. Bu oldukça yüksek bir örnek, ama iş parçacıkları kesinlikle cpu'nuzu biraz daha zorlamak için kullanılabilir.


Daha spesifik olarak, bir iplik olabilir bekleyen I / O başka hesaplama yapar iken. G / Ç CPU döngüleri (önemli) yaptıysa, ayrı bir iş parçacığında çalıştırmanın bir yararı olmazdı. Bunun yararı, I / O ipliğiniz başparmaklarını döndürürken büyük bir alüminyum silindirin yerine dönmesini beklerken veya paketlerin İzlanda'dan tel üzerinden gelmesini beklerken ya da her neyse, hesaplama ipliğinizin çalışabilmesidir.
Ken

2

İşlemci veya CPU, sisteme takılan fiziksel yongadır. Bir işlemci birden fazla çekirdeğe sahip olabilir (bir çekirdek, çipin talimatları uygulayabilen parçasıdır). Bir çekirdek, aynı anda birden çok iş parçacığı yürütebiliyorsa, işletim sistemine birden çok sanal işlemci olarak görünebilir (iş parçacığı tek bir komut dizisidir).

İşlem, bir uygulamanın başka bir adıdır. Genel olarak süreçler birbirinden bağımsızdır. Bir işlem ölürse, başka bir işlemin de ölmesine neden olmaz. Süreçlerin iletişim kurması veya bellek veya G / Ç gibi kaynakları paylaşması mümkündür.

Her işlemin ayrı bir adres alanı ve yığını vardır. Bir işlem, her biri talimatları aynı anda yürütebilen birden fazla iş parçacığı içerebilir. Bir işlemdeki tüm iş parçacıkları aynı adres alanını paylaşır, ancak her iş parçacığının kendi yığını vardır.

Umarım bu tanımlar ve bu temel ilkeleri kullanarak daha fazla araştırma yapmak anlayışınıza yardımcı olacaktır.


2
Bunun sorusuna nasıl hitap ettiğini anlamıyorum. Onun sorusuna ilişkin yorumum, çekirdeklerin iş parçacığı kullanımı ve mevcut kaynakların optimum kullanımı ya da sayılarını artırdıkça iş parçacıklarının davranışı ya da bu satırlar boyunca bir şey hakkındadır.
David

@David belki de soruma doğrudan bir cevap değildi, ama hala okuyarak öğrendiğimi hissediyorum.
Nick Heiner

1

İpliklerin ideal kullanımı, aslında, çekirdek başına birdir.

Ancak, yalnızca eşzamansız / engellemeyen G / Ç'yi kullanmadığınız sürece, CPU'nuzu kullanmayacak bir noktada G / Ç üzerinde iş parçacıklarının engellenmesi ihtimali yüksektir.

Ayrıca, tipik programlama dilleri CPU başına 1 iş parçacığı kullanmayı biraz zorlaştırır. Eşzamanlılık (Erlang gibi) etrafında tasarlanan diller, fazladan iş parçacığı kullanılmamasını kolaylaştırabilir.


Periyodik görevler için iş parçacıklarını kullanmak çok yaygın ve hoş bir iş akışıdır ve bir çekirdeği çalmaları idealden çok daha az olacaktır.
Nick Bastin

@Nick Bastin: Evet, ancak bu görevleri bir görev kuyruğuna yapıştırmak ve bu kuyruktan (veya benzer bir stratejiden) yürütmek daha etkilidir. Optimal verimlilik için, çekirdek başına 1 iplik, gereksiz içerik anahtarlamasının ek yükünü ve ekstra istiflerin tahsis edilmesini önlediğinden hepsini yener. Ne olursa olsun, periyodik görev gereken cpu olarak 'etkin' ise bir çekirdek çalmak yalnızca gerçekten (varsa hiper iş parçacığı gibi artı şeyler) çekirdek başına bir görevi gerçekleştirebilir.
kyoryu

@Nick Bastin: Ne yazık ki, ana cevapta söylediğim gibi, modern dillerin çoğu, bunu etkili bir şekilde yapan bir sistemi kolayca uygulamak için kendilerini iyi bir şekilde ödünç vermiyor - sonuçta dilin tipik kullanımıyla savaşmak için bir miktar mücadele ediyorsunuz.
kyoryu

Demek istediğim, çekirdek başına bir iş parçacığının en uygun olmadığı değil, çekirdek başına bir iş parçacığının bir boru rüyası olduğu (gömülmedikçe) ve onu vurmaya çalışmak için tasarım zaman kaybıdır, bu yüzden de Kullandığınız iş parçacığı sayısını optimize etmek yerine, sizin için kolaylaştıran şeyi yapın (ve modern bir zamanlayıcıda daha az verimli değildir). İplikleri iyi bir sebep olmadan döndürmeli miyiz? Tabii ki hayır, ama gereksiz yere bilgisayar kaynaklarını boşa harcıyorsanız, diş çekme işlemine bakılmaksızın bir endişe kaynağıdır.
Nick Bastin

@Nick Bastin: Özetlemek gerekirse, çekirdek başına bir iplik idealdir, ama aslında bunu başarmak pek olası değildir. Böyle bir şeye ulaşmanın ne kadar muhtemel olduğundan bahsederken muhtemelen 'biraz zordan' daha güçlü olmalıydım.
kyoryu

1

Bazı API'ların tasarlanma şekli, başka seçeneğiniz yok bunları ayrı bir iş parçacığında (engelleme işlemleri olan herhangi bir şey) çalıştırmaktan . Buna bir örnek Python'un HTTP kütüphaneleri (AFAIK) olabilir.

Genellikle bu bir sorun değildir (eğer bir sorun varsa, işletim sistemi veya API alternatif bir eşzamansız çalışma modu ile gönderilmelidir, yani:) select(2), çünkü muhtemelen iş parçacığının I / Ey tamamlanma. Bir şey için yoğun hesaplamalar yapıyor Öte yandan, sen sahip söz hakkından daha ayrı bir konu koymak için, GUI iplik (manuel çoklama tadını sürece).


1

Bunun çok iyi cevapları olan çok eski bir soru olduğunu biliyorum, ama burada mevcut ortamda önemli olan bir şeye dikkat çekmek için buradayım:

Çok iş parçacıklı işleme için bir uygulama tasarlamak istiyorsanız, belirli bir donanım ayarı için tasarlamamalısınız. CPU teknolojisi yıllardır oldukça hızlı bir şekilde ilerliyor ve çekirdek sayıları giderek artıyor. Uygulamanızı kasıtlı olarak yalnızca 4 iş parçacığı kullanacak şekilde tasarlarsanız, kendinizi bir okta çekirdekli sistemde (örneğin) sınırlandırırsınız. Şimdi, 20 çekirdekli sistemler bile piyasada mevcut, bu nedenle böyle bir tasarım kesinlikle faydadan daha fazla zarar veriyor.


0

İlk varsayımınıza yanıt olarak: çok çekirdekli makineler aynı anda yalnızca tek bir işlemin birden çok iş parçacığını değil, birden çok işlemi çalıştırabilir.

İlk sorunuza yanıt olarak: birden çok iş parçacığının noktası genellikle bir uygulamada aynı anda birden çok görevi gerçekleştirmektir. İnternetteki klasik örnekler, posta gönderip alan bir e-posta programı ve sayfa isteklerini alan ve gönderen bir web sunucusudur. (Windows gibi bir sistemi yalnızca bir iş parçacığı veya yalnızca bir işlem çalıştıracak şekilde azaltmanın aslında imkansız olduğunu unutmayın. Windows Görev Yöneticisi'ni çalıştırın ve genellikle birçoğu birden çok iş parçacığı çalışacak olan uzun bir etkin işlem listesi görürsünüz. )

İkinci sorunuza yanıt olarak: çoğu işlem / iş parçacığı CPU'ya bağlı değildir (yani sürekli ve kesintisiz çalışmaz), bunun yerine durup sık sık G / Ç'nin bitmesini bekleyin. Bu bekleme sırasında, diğer işlemler / evreler bekleme kodundan "çalmadan" (tek çekirdekli bir makinede bile) çalışabilir.


-5

Bir iş parçacığı, bir işlem dizisi kadar basit bir kod yazmanıza olanak tanıyan, kodun başka bir kodla araya girdiğini veya IO için bekletildiğini veya başka bir iş parçacığını beklerken (belki biraz daha farkında olarak) olaylar veya mesajlar.


Bunu, aşağı oylardan beri daha fazla örnek ekleyerek düzenleyebilirdim - ancak performansı ölçeklendirmek için bir iş parçacığı (veya bu bağlamda neredeyse hiçbir fark yok) icat edilmedi, daha ziyade asenkron kodu basitleştirmek ve karmaşık durum makineleri yazmaktan kaçınmak için icat edildi programda mümkün olan tüm süper durumları ele almak zorundaydı. Aslında büyük sunucularda bile tipik olarak bir CPU vardı. Sadece cevabımın neden anti-yararlı olarak değerlendirildiğini merak ediyorum?
KarlP

-8

Mesele şu ki, programcıların büyük çoğunluğu bir devlet makinesinin nasıl tasarlanacağını anlamıyor. Her şeyi kendi iş parçacığına koyabilmek, programcıyı devam eden farklı hesaplamaların durumunu nasıl verimli bir şekilde temsil edeceğini düşünmekten kurtarır, böylece kesintiye uğrayabilir ve daha sonra devam ettirilebilir.

Örnek olarak, çok yoğun bir işlem olan video sıkıştırmayı düşünün. Bir gui aracı kullanıyorsanız, muhtemelen arayüzün yanıt vermesini istersiniz (ilerleme durumunu göster, istekleri iptal etme, pencere yeniden boyutlandırma vb.). Böylece, kodlayıcı yazılımınızı aynı anda büyük bir birimi (bir veya daha fazla kare) işlemek ve UI'den ayrı olarak kendi iş parçacığında çalıştırmak için tasarlarsınız.

Tabii ki, devam eden kodlama durumunu kaydedebilmenin güzel olacağını fark ettikten sonra, programı yeniden açmaya veya kaynağa aç bir oyunu oynamak için kapatabilir, durum makinelerini nasıl tasarlayacağınızı öğrenmelisiniz. başlangıç. Ya bu, ya da işletim sisteminizin yeni bir hazırda bekletme sorununu tasarlamaya karar verirsiniz, böylece tek tek uygulamaları diske askıya alabilir ve devam ettirebilirsiniz ...


7
-1 değerinde değil, ama cidden, bu konuda kimsenin söylediğini duyduğum en aptalca gizemli şey. Örneğin, bir devlet makinesini uygulamada sorun yaşamıyorum. Hiç yok. Kodları daha net ve bakımı daha kolay bırakan başka araçlar olduğunda onları kullanmaktan hoşlanmıyorum . Devlet makinelerinin yerleri vardır ve bu yerlerde eşleştirilemezler. CPU-yoğun işlemlerin GUI güncellemeleri ile karıştırılması bu yerlerden biri değildir. En azından coroutines orada daha iyi bir seçimdir, iplik geçirme daha da iyidir.
SADECE benim doğru görüşüm

Cevabımı değiştiren herkes için, bu konuların kullanımına karşı bir tartışma DEĞİLDİR! Harika bir durum makinesini kodlayabiliyorsanız ve gerekmese bile durum makinelerini ayrı iş parçacıklarında çalıştırmanın mantıklı olduğundan emin olun. Benim yorumum, çoğu zaman iş parçacığı kullanma seçiminin, çoğu programcının başka bir faydadan ziyade "çok zor" olduğunu düşündüğü durum makineleri tasarlamadan kaçınma arzusundan yapıldığıydı.
R .. GitHub BUZA YARDIMCI DURDUR
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.