“Çok çekirdekli” dostu olmadığını iddia eden programlar


17

Bu ifadeyi veya benzerlerini, zaman zaman, çok çekirdekli işlemcilerden tam olarak yararlanmak üzere tasarlanmadığını iddia eden bir programa atıfta bulunarak görürsünüz. Bu, özellikle video oyunu programlamasında yaygındır. (tabii ki birçok programın eşzamanlılığı yoktur ve buna temel komut dosyaları vb. gerek yoktur).

Bu nasıl olabilir? Birçok program (özellikle oyunlar) doğal olarak eşzamanlılık kullanır ve işletim sistemi CPU üzerinde görev planlamasından sorumlu olduğundan, bu programlar doğal olarak mevcut çoklu çekirdeklerden yararlanmıyor mu? Bu bağlamda "çoklu çekirdeklerden faydalanmak" ne anlama gelir? Bu geliştiriciler aslında işletim sistemi görev zamanlamasını yasaklıyor ve yakınlığı veya kendi zamanlamasını zorlıyor mu? (Büyük bir istikrar sorunu gibi görünüyor).

Ben bir Java programcısıyım, bu yüzden belki de soyutlamalar veya ne olursa olsun bununla uğraşmak zorunda kalmadım.


11
Büyük bir olasılık, tek işlemcili / çekirdek sistemde çalışan, ancak birden fazla işlemcinin / çekirdeğin gerçek eşzamanlılığıyla kopan senkronizasyonda kısayolların alınmasıdır.
Bart van Ingen Schenau

@BartvanIngenSchenau: Bu doğru. Bunu genişletmeli ve bir cevap olarak göndermelisiniz. Bence tüm diğerleri bu noktayı kaçırdı.
kevin cline

1
@Bart'ın gerçekten yakın olduğunu düşünüyorum. Ancak, s / work / çalışıyor / görünür ve işarete daha yakın olacaktır.
Ben Voigt

bir kenara - bu bir programcı yerine bir kullanıcı olarak deneyim yaşadım - Windows XP'de Zemin Kontrolü 2. Düzgün çalışabilmesi için çok çekirdekli bir sistemde sadece bir çekirdeğe çekirdek yakınlığı ayarlamam gerekiyordu, aksi takdirde tüm animasyonlar (tüm oyunu etkiliyor) 10x hızda çalışacaktı, bu da bir meydan okumadan daha sonra bir süre sonra biraz can sıkıcı bir hal aldı . Oyunlar üzerinde herhangi bir çalışma yapmadım ama bence oyunun bir kısmı işlemciye güveniyor gibiydi, aynı anda sadece belirli miktarda iş yapıyor.
jammypeach

Yanıtlar:


28

İyi eşzamanlılık, bir uygulamaya birkaç iş parçacığı atmaktan ve en iyisini ummaktan çok daha fazlasını gerektirir. Bir programın utanç verici bir şekilde saf sıralamaya ne kadar eşzamanlı olarak gidebileceği konusunda bir aralık vardır . Herhangi bir program, bir problemin veya algoritmanın ne kadar ölçeklenebilir olduğunu ifade etmek için Amdahl yasasını kullanabilir . Utanç verici şekilde paralel bir uygulama için birkaç yeterlilik:

  • Paylaşılan durum yok, her işlev yalnızca geçirilen parametrelere bağlıdır
  • Fiziksel cihazlara erişim yok (grafik kartları, sabit sürücüler, vb.)

Başka nitelikler de var, ancak sadece bu ikisi ile, özellikle oyunların neden birden fazla çekirdekten yararlanmayı düşündüğünüz kadar kolay olmadığını anlayabiliriz. Birincisi, oluşturulacak dünyanın modeli, fizik, hareket, yapay zeka uygulamak vb. Gibi farklı işlevler olarak paylaşılmalıdır. İkincisi, bu oyun modelinin her karesi bir grafik kartı ile ekranda işlenmelidir.

Adil olmak gerekirse, birçok oyun üreticisi üçüncü taraflarca üretilen oyun motorlarını kullanır. Biraz zaman aldı, ancak bu üçüncü taraf oyun motorları eskisinden çok daha paralel.

Etkin eşzamanlılıkla başa çıkmada daha büyük mimari zorluklar var

Eşzamanlılık, arka planda görevleri yürütmekten eşzamanlılık için tam bir mimari desteğe kadar birçok şekilde olabilir. Bazı diller, ERLANG gibi çok güçlü eşzamanlılık özellikleri sunar , ancak uygulamanızı nasıl oluşturduğunuz hakkında çok farklı düşünmenizi gerektirir.

Her programın tam çok çekirdekli desteğin karmaşıklığına gerçekten ihtiyacı yoktur. Bu örneklerden biri vergi yazılımı veya herhangi bir form tabanlı uygulamadır. Zamanınızın çoğu kullanıcının bir şeyler yapmasını beklemek için harcandığında, çok iş parçacıklı uygulamaların karmaşıklığı o kadar da kullanışlı değildir.

Bazı uygulamalar web uygulamaları gibi daha utanç verici bir şekilde paralel bir çözüme sahiptir. Bu durumda, platform utanç verici bir şekilde paralel olarak başlar ve iş parçacığı çekişmesi uygulamak zorunda kalmazsınız.

Alt çizgi:

Birden fazla iş parçacığından (ve dolayısıyla çekirdeklerden) yararlanılmadan tüm uygulamalar gerçekten zarar görmez. Bu şekilde incinenler için, bazen hesaplamalar paralel işlemeye uygun değildir veya koordine etmek için ek yük, uygulamayı daha kırılgan hale getirir. Ne yazık ki, paralel işleme hala iyi olması gerektiği kadar kolay değildir.


Bu harika bir analiz. Yine de beni rahatsız eden bir şey, gerçek dünyadaki programlarla ilgili noktanızın genellikle utanç verici bir şekilde paralel olmaması ve bu nedenle paralel hale getirilmesinin zor olması: Aynı şeyi paralel olarak yapmak imkansız olsa da, paralel olarak farklı şeyler yapmak çok kolay olabilir ( örneğin bir boru hattı mimarisinde veya ayrı bir kullanıcı arayüzü iş parçacığıyla).
amon

8
Asıl nokta, paralel yürütme için tasarım yapmanız gerektiğidir ve eğer yapmazsanız tasarım eksikliğinizle kısıtlanırsınız. Paralel olarak farklı şeyler yapmanın çok kolay olabileceğini kabul ediyorum , ancak yüksek kullanıcı beklentilerine sahip mevcut bir uygulama değilse. Bu durumda bunu mümkün kılmak için yeniden yazılması gerekebilir. Yeniden yazma doğal olarak risklidir, ancak bazen onlar için iyi bir argüman yapabilirsiniz. Mümkün olduğunca çok kodu koruyarak paralel işlemeyi en üst düzeye çıkaran birkaç yeniden yazma yaptım. Çok fazla gizli faktör var.
Berin Loritsch

Mükemmel cevap. Bazı sistemlerin paralelleştirilmesinde yalnızca azalan getiriler olabileceğini değil, aynı zamanda bazılarının paralel hale getirilmesi için gereken ek yük nedeniyle daha yavaş olabileceğini vurgulamakta fayda var . Özellikle, çok sayıda semafor / kilit ve bağlam anahtarlamanın çalışma zamanı üzerinde olumsuz etkileri olabilir. Özellikle bağlam değiştirme, önbelleğin etkinliğini azaltabilir, bu da sisteminizi optimize etme noktasındaysanız önemsiz bir konudur. OP'nin özellikle oyun motorları örneği, önbelleği optimize etme hakkında paralel erişimden çok daha fazla işitmeyi hatırlamama neden oluyor.
Gankro

35

Birçok program (özellikle oyunlar) doğal olarak eşzamanlılık kullanır,

Hayır, aslında tam tersi. Çoğu uygulama tek bir iş parçacığı zihninde yazılır ve geliştirici (ler) eşzamanlılığı desteklemek için hiçbir zaman gerekli değişiklikleri yapmamıştır.

C, C ++ ve C # 'da, uygulamaya yeni iş parçacıklarını ve / veya işlemleri başlatmasını açıkça söylemeniz gerekir.

Bence iş parçacıklarının planlamasına çok fazla odaklanıyorsunuz ve potansiyel iş parçacıkları içindeki veri işlemeye yeterli değilsiniz. Verileri iş parçacıkları ve / veya işlemler arasında paylaşmak bir tür senkronizasyon gerektirir. Bir uygulamayı birden çok iş parçacığı kullanacak şekilde değiştirirseniz, ancak bu eşitlemeyi yerine getiremezseniz, büyük olasılıkla koddaki hataları izlemek çok zor görürsünüz.

Üzerinde çalıştığım çok iş parçacıklı uygulamalar için, genellikle hiçbir zaman gönderim ve yalnızca veri senkronizasyonu konusunda endişelenmedim. Sevkıyat konusunda endişelenmem gereken tek şey yanlış veri senkronizasyonu nedeniyle yarış koşullarını takip etmemdi.

Genellikle, bir uygulama birden fazla çekirdek kullanamayacağını söylediğinde, veri manipülasyonunu korumak için senkronizasyona sahip olmadıkları anlamına gelir.


Bu, büyük geliştirici / yayıncıların yeni modern programları için bile geçerli mi? Oturup bir program yazdığımda, tasarım aşamasında düşündüğüm ilk şeylerden biri eşzamanlılığa ihtiyacım var mı? Çünkü çok farklı bir tasarıma neden olabilir. Özellikle oyunların belirli bir düzeyde eşzamanlı olması gerekir, aksi takdirde bin ekran modelinden biri bir şey yapmaya çalıştığında oyun donar ...?
SnakeDoc

5
@SnakeDoc - Sanırım orada alan adlarını karıştırıyorsun. Büyük Oyun şirketleri kesinlikle eşzamanlılık düşünülerek yazıyor, ancak henüz bir Big Game co'nun eşzamanlılığı desteklemediği bir oyun görmedim. Eşzamanlılığı destekleyemediğini gördüğüm uygulamalar ve oyunlar genellikle bu zihniyetle başlamayacakları küçük dükkanlardan / bireysel geliştiricilerden. Ve uygulamanın evriminin bir noktasında, gerçeğin ardından eşzamanlı olarak cıvatalamak imkansız hale gelir. Ve bazı uygulamalar hiçbir zaman eşzamanlı olmayı haklı çıkarmaya yönelik değildi.

Ayrıca bazı oyunlar, oyun motorunu güncellemek zorunda kalmadan (kod uygulaması) yeni içerik (grafik ve oyun) üzerinde gelişir. Bu nedenle, oyun motoru teknolojide yıllar geride kalabilir.
rwong

6
@SnakeDoc: Binlerce ekran modeliyle uğraşmak için eşzamanlılığa ihtiyacınız yok. Oyundaki her nesnenin onu simüle etmek için kendi iş parçacığına ihtiyacı yok gibi değil; bir iş parçacığı, ekran üzerindeki her şeyin güncellemelerini her zaman aralığında işleyebilir.
user2357112 Monica

13

Bu, çoklu çekirdeklerle ilgili olduğu kadar çoklu çekirdeklerle de ilgili değildir. İşletim sistemi bir iş parçacığını istediği çekirdek üzerinde çalışacak şekilde zamanlayabilir ve bu zamanlama planlanan program için şeffaftır. Ancak, birçok program birden çok iş parçacığı kullanılarak yazılmaz, bu nedenle aynı anda yalnızca bir çekirdek üzerinde çalışabilirler.

Neden tek iş parçacıklı bir program yazayım? Yazmak ve hata ayıklamak daha kolaydır: bir şey birbiri ardına gerçekleşir (aynı anda birden fazla şey yerine ve birbirlerinin yollarına girmek yerine). Veya programınız çok çekirdekli makineleri (eski oyunlarda olduğu gibi) hedeflemiyor olabilir. Bazı durumlarda, bağlam anahtarlarından ve iş parçacıkları arasındaki iletişimin paralel yürütme tarafından kazanılan hızdan daha ağır basması durumunda çok iş parçacıklı bir program tek iş parçacıklı bir sürümden daha yavaş çalışabilir (programın bazı bölümleri paralelleştirilemeyebilir).


8

Bu tam bir cevap değil. Bu bir uyarıcı masal.

Bir gün eşzamanlı programlama dersimdeki öğrencileri paralel bir çabuk göstereceğim diye düşündüm. Quicksort iyi paralellik göstermeli, diye düşündüm. İki iplik kullandım. Tek çekirdekli bilgisayarımda çalıştırdım. Sonuçlar:

  • Tek iş parçacıklı bir sürüm için 14 saniye.
  • 2 iş parçacıklı sürüm için 15 saniye.

Bu beklediğim ile ilgiliydi.

Sonra daha yeni, çift çekirdekli bir makinede denedim.

  • Tek iş parçacıklı sürüm için 11 saniye.
  • 2 iş parçacıklı sürüm için 20 saniye.

İki iş parçacığı, kalan görevlerin bir sırasını paylaştı. Kuyruk nesnesinin alanları bir çekirdeğin önbelleği ile diğerinin arasında ileri geri karıştırılıyor gibi görünüyor.


2
Kaç dizi öğeyle test yaptınız? Çok çekirdekli programlama, önbellek hattı çakışmalarını önlemek için verilerin kopyalanmasını gerektireceğinden, belki de mergesort daha uygun olurdu?
rwong

2
@rwong 10.000.000 dizi öğesi vardı. Kesinlikle birleştirme iyi paralellik gösterir. Birleştirme türünü kullansaydım, muhtemelen yararlı bir ders öğrenemezdim.
Theodore Norvell

1
@ArlaudPierre Herhangi bir algoritmayı paralelleştirmeyi düşüneceğim. Quicksort ilginçtir, çünkü bunun için görev çantası yaklaşımını kullanabilirsiniz. Görevler bağımsız olduğu için sezgim utanç verici bir paralellik örneği olmasıydı. Biraz ayar yaptıktan sonra, aslında 2'ye yakın bir hıza sahip olduğunu belirtmeliyim
Theodore Norvell

1
@Jules Cevap yük dengelemedir. Ayrıca iş parçacığı sayısını değiştirmek için kolaylaştıracak bir şekilde yazmak istedim. Yaklaşımınız 2'nin kuvvetleri için güzelleşir, ancak diğer ipliklerin sayısı için o kadar iyi değildir.
Theodore Norvell

2
@MaciejPiechotka Ahlak, önerdiğiniz her şeydir. Ancak OP'ye geri dönersek, en alakalı ahlaki, çok iş parçacıklı bir programın, aksi sağlamak için çaba sarf edilmedikçe, çok çekirdekli bir mimaride tek çekirdekli bir mimariden çok (çok) daha yavaş çalışabileceğini düşünüyorum.
Theodore Norvell
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.