Programlamada çoklu çekirdek için işlemleri atamak mı gerekiyor?

Öncelikle sahip olduğunuz kafa karışıklığını giderelim. @TerabyteForever güzel bir noktaya parmak basmış ve kodların "multithreaded" olmasından bahsetmiş. Bu, çok "thread"li işlemler demektir. Siz bir kod yazarken kodu paralel parçalara bölmek isterseniz eğer kodu birden fazla thread çalıştıracak şekilde yazarsınız. Ancak bunu farklı işlemlere (process) bölerek de yapabilirsiniz. Örneğin Google mühendisleri Chrome'u tasarlarken karar aşamasında her tarayıcı penceresinin bir veya birkaç farklı threadde çalışması yerine yeni bir işlem açmasına karar vermişlerdi. Her pencere için yeni bir işlem açmanın bellekte ve diğer kaynaklarda bedeli daha fazla olsa bile Chrome'un daha sağlıklı çalışmasını sağlıyordu.

İşletim sistemi penceresine dönelim. Bir işletim sisteminin en temel görevi kaynak yönetimidir. Kaynak yönetiminin işlemleri ilgilendiren parçasına "process scheduling" denir. Windows bunu öncelik atamasıyla çalışacak şekilde preemptive olarak yapar. İşlemler, kodlarında yazıldığı gibi threadleri çağırır. Threadler ise varsayılan herhangi bir işlemci çekirdeği üzerinde çalışabilir ancak işletim sistemi bunu kısıtlayabilir. Örneğin Discord'u açarsınız, işletim sistemi Discord'un threadleri için sadece ilk 3 çekirdeği ayırır. Discord'a ayrılan işlemci kaynakları bu 3 çekirdekten verilir. Buna "process affinity" deniyor. Görev Yöneticisi açarak bunu kendiniz gözlemleyebilir ve ayarlayabilirsiniz.

Eki Görüntüle 1387824
Burada Discord'un işlemi her çekirdekte çalışabilir şekilde işaretlenmiş.​

Scheduling işlemi gerçekten derya deniz bir işlem. Ancak her programcının bilmesi gereken bir konu. Daha fazla okuma yapmak için Microsoft'un kaynağını aşağı bırakıyorum.

Aynen de böyle. Scheduler her işlemin bilgisayarda tek bir işlemmiş gibi çalışmasını sağladığı için multithreading uygulama yazan herkesin bilmesi gereken bir şey. Race condition durumunu daha iyi anlamak için.
 
Duruma gore degisir.

Bazi islemciler sen single thread de yazsan bunu paralelize edebilirler. ARM gibi instruction size fixed olan mimarilerde bu daha kolay. ( ILP )


Ote yandan yazdigin "single thread" uygulama birden fazla defa instantiate edilerek de "paralelize" edilebilir. Memory paylasmiyorlar ama bir paralelizasyon var. Producer - Consumer mantigi bu biraz.

Programlama yaparken cekirdek sayisini degil, thread'i dusunursun. Multi-thread calisacagini bildigin uygulamayi concurrent sekilde yazarsin.


Dile, frameworke, donanima ve nasil calistirilacagina gore uygulamanin nasil paralelize edilecegi degisir. Concurrency ile ilgili gereklilikleri yerine getirirsen problem yasamazsin. Super-scalar bir islemcide calistiracagin kodun hangi cekirdekte schedule edilecegini bilemezsin.


Ornegin Java 'da normal splitIterator'u paralelize edebilmen icin tek boolean vermen yeterli. Yani kodunda super bir degisiklik gerekmiyor paralelizasyon icin. Onemli olan concurrency'dir. ( Immutability, Thread-safety vs )

 

Geri
Yukarı