Haziran sıcaklarıyla birlikte sıcak sıcak çıkan yeni sayımızdan herkese merhaba :) Bir yılı aşkın süredir yayın yapmakta olan bergimize gösterdiğiniz büyük ilgi için öncelikle çok teşekkür ederiz. Sayenizde her sayımızda biraz daha sağlam adımlarla bilgisayar dünyasında turluyoruz. Haydi gelin bu ayki serüvenimize bilgisayar bilimi köşemizden çoklu işlemcili sistemler (multiprocessor systems) arasında dolaşarak başlayalım. Biliyorsunuz eskiden bilgisayarları hızlandırmak demek, sadece saat sinyalini daha hızlı çalıştırmakla eşdeğerdi. Yani bilgisayarların temel yapıtaşı olan transistörlerin daha hızlı durum değiştirebilmeleriydi. Bunun için, transistör boyutlarını küçülttükçe, yeni fabrikasyon yöntemleri kullanarak devreyi küçültüp, saat sinyalinin tüm devreye yayılmasını hızlandırdıkça, bilgisayarlarımız hızlanıyordu. Ancak bir süre sonra, küçültmek başka sorunlara yol açmaya başladı. Bilgisayarı hızlandırdıkça harcadığı güç artıyor, böylece çıkan ısı miktarı artıyordu. Küçülttükçe de bu ısının yayıldığı alandan atılması zorlaşıyordu. Örneğin 1 GHz'den 10 GHz'e yükselmek demek, 10 kat fazla güç ve 10 kat fazla ısı demek. Yani artık sorunumuz işlemcilerle değil, işlemcilerden büyük olan soğutucularlaydı. Bu gelişmeler ve sınırlamalar doğrultusunda, yeni bir yaklaşım seçildi: paralel bilgisayarlar.
PARALEL BİLGİSAYARLAR
Paralel programlama dilleri dışında, programlama sıralı yapıldığı için; çift çekirdek bilgisayar demek her şey iki katı hıza çıkacak anlamına gelmiyor. Evet verimlilik artıyor; ancak işlemciyi de kullanılabilir bir kaynak olarak görürsek, bu kaynağın kullanılması sonuçta yine sıralı olarak yapılan bir şey. Şimdi bunları göz önüne alarak geliştirilen üç modelden bahsetmek istiyorum**.**
1) Ortak hafızalı çoklu işlemci İki ila bin işlemcinin ortak bir hafıza üzerinden iletişmelerinden oluşan sistemde, her işlemcinin tüm hafızaya eşit ulaşım hakkı vardır. Okuma ve yazma işlemleri 10-50 nanosaniye sürer. Basit görünen bu sistemin inşası aslında çok daha karışıktır, birazdan anlatacağım gibi.
2) Mesaj ileten çoklu bilgisayar İşlemciler yine birbirinden ayrıdır; fakat bu sefer iletişim yüksek-hızlı bir karşılıklı bağlanma ile sağlanır. Çünkü bu modelde bellekler de birbirinden ayrılmıştır ve işlemcilerle bellekler eşleştirilmiştir, yani her bellek sadece bir işlemci tarafından ulaşılabilir. İletişimi sağlayan bağlantı üzerinden işlemciler birbirlerine mesaj gönderirler. Bağlantı gelişmiş ise mesaj hızı 10-50 mikrosaniyeye kadar çıkar; fakat yine de ilk modelden çok daha düşüktür . Çoklu bilgisayarları inşa etmek çoklu işlemcilerden çok daha kolaydır, ama global bir bellek olmadığından bunların da programlanması zordur.
3) Dağıtılmış sistem Bu modelde, bütün olarak sistemler bir geniş alan ağı sayesinde (internet gibi) bağlanmışlardır. Dolayısıyla bütün sistemler kendi belleklerine sahiplerdir ve iletişim mesaj gönderme yoluyla olur. Bir önceki modele benzer; fakat seyrek-eşleştirilmiş bu sistemin sık-eşleştirilmiş önceki sistemden farkı mesaj iletim hızının 10-50 milisaniyeye kadar çıkmasıdır.
Bu modellerin farkları hız, yayıldıkları alan ve mantıksal yapılanmaları. Farkındaysanız hızları arasında 103 kat fark var, bu da bir gün ve üç yıl arasındaki fark demek. İlk modelin bilgisayarımızın içinde minik bir alan olduğu, son modelin ise internete bağlı bilgisayarların kapladığı alan olduğunu varsayarsak, alanlar arasında da bir hayli fark olduğu aşikar. Bu yazımda çoklu işlemcilere göz atacağız, diğer iki modeli gelecek yazılarımızda bulabilirsiniz.
ÇOKLU İŞLEMCİLER
Çoklu işlemciler çıkana kadar bütün programlama, işletim sisteminin çalışma yapısı, girdi çıktı araçlarının yapılanması, kısaca işlemcinin yer aldığı bütün alt sistemler tek bir işlemciyi baz alınarak yapıldı. Bundan dolayı çoklu işlemci kavramıyla hem donanımsal açıdan, hem de işletim sistemi açısından bazı yaklaşımlar yıkıldı. Sorun, eskiden belleğe okuma/yazma işlemi yapabilen tek bir bölüm varken, çoklu işlemcilerde belleğe erişimin birden çok olması, dolayısıyla bir işlemcinin yazdığı bir adresten bir sonraki okuyuşunda farklı bir değer alabilmesiydi. Buna iki farklı donanımsal yaklaşım var. Farkları ise bellekten okuma/yazma işleminin her kelime için eşit olması veya olmaması.
Çoklu İşlemci Donanım Türleri
1) UMA (Uniform Memory Access, Düzgün Bellek Erişimli) UMA çoklu işlemcilerinde her işlemcinin belleğe erişiminde bir kelimeyi okuması veya yazması için geçen süre aynıdır. Yapı olarak bütün işlemciler ve ortak bellek bir veriyoluna bağlanmıştır ve belleğe ulaşım bu yolla olur. Bir işlemci belleğe ulaşmak istediğinde veriyolu boşalana kadar bekler, boşaldığında istediği bellek bölümünün adresini veriyoluna koyar, bazı sinyaller gönderir, ve bellek istenen adresin içindekileri veriyoluna koyana kadar bekler. Fakat yine ufak bir sorun var, az sayıda işlemci ile veriyolu kullanımı verimli veya normal olabilir, ancak 30 işlemcinin bir veriyolunu kullanması ve beklemesi sistemi çok yavaşlatan bir durum. Bunun için yine önbellekleme yöntemi bir çözüm olarak getirilmiş, her işlemcinin kendi önbelleği var ve veriyoluna aktarım yapmadan önce bu önbelleğe yazıyor, böylece beklemesi gerekmiyor, veriyolu uygun oldukça önbellektekiler gönderiliyor. Ancak bu sefer de başka bir sorun ortaya çıkıyor, ki her önbellekleme kullanımında karşılaşıldığı gibi, bir verinin değiştirilmiş kopyalarının farklı işlemci önbelleklerinde bulunmasından dolayı veri tutarsızlığı olabiliyor. Bunun çözümü de önbellekleri okunabilir ve yazılabilir olarak ayırmak. Okunabilir önbelleklerdeki bilgiler birden çok önbellekte bulunabilirken, yazılabilir önbelleklerdekilerin değiştirilmiş kopyası başka bir önbellekte bulunmamalı. Bunun için bir yazılabilir önbellekteki bir bilgi belleğe yazılacağı zaman, veriyolu diğer yazılabilir önbelleklere bakar. Eğer hepsinde bellektekiyle aynı olan bir kopya varsa (yani temiz bir kopya), belleğe yazma işlemini gerçekleştirir. Ama birinde olsun değiştirilmiş bir kopya varsa, dizayn farkına göre ya o değiştirilmiş kopya önce yazılır sonra modifiye edilir, ya da değiştirilmiş kopya şu an yazmak isteyen önbelleğe iletilir. Veriyolu kullanımı dışında başka bir UMA örneği de, çapraz anahtarlama kullanmak. Bu yöntemde, ayrılan işlemci ve bellekler ızgara yapısında ayrı veriyolları kullanılarak iletişim sağlanır. Veriyolunu beklemek gibi bir sorun olmamasından ötürü önbelleklemekten çok daha verimli olmasına rağmen, bunun için gerekli devreleri üretmek çok pahalıdır. İşlemci sayısı arttıkça anahtar sayısı işlemcinin karesi ile doğru orantılı olarak artması da dezavantajıdır.
2) NUMA (Nonuniform Memory Acces, Düzgün Olmayan Bellek Erişimli) Tek veriyollu UMA ve çapraz anahtarlama, işlemci sayısıyla sınırlı ve pahalı oldukları için, yüz ve üzeri işlemci sayısında NUMA kullanılır. UMA'dan farkı, işlemcilerin belleğin her bölgesine aynı sürede erişimi olmamasıdır. NUMA'nın karakteristiği, tüm işlemcilere açık olan tek bir adres alanı olması, uzaktaki belleğe yükleme ve depolama fonksiyonlarıyla ulaşması ve uzaktaki belleğe yerel bellekten daha uzun sürede ulaşılmasıdır. Bunun en yaygın örneği, dizin bazlı çoklu işlemcidir.
Çoklu İşlemci İşletim Sistemi Türleri
Donanımsal olduğu gibi, işletim sistemi açısından da çoklu işlemcilerin farklı kullanım türleri vardır. Donanımda işlemcilerle bellek ilişkisinin eniyileştirilmesi söz konusuyken, şimdi işlemcilerle işletim sistemi ilişkisini inceleyeceğiz.
1) Her işlemcinin kendi işletim sistemi olması Çoklu işlemci işletim sistemlerinin en basitidir. İşletim sistemleri farklı olacağından bellek her işletim sistemi için (yani her işlemci için) parçalanmıştır. İşletim sistemi veri yapıları farklıdır ve ayrılmış bölümlerde bulunur, yani her işlemcinin kendi özel hafızası ve özel işletim sistemi kopyası olduğundan birçok bağımsız bilgisayarımız varmış gibi olur. Çekirdek kodunu, işletim sistemi kodunu, belleğin ortak bölümünde tutmak bu sisteme getirilebilecek bir iyleştirmedir. Bu yaklaşımın dezavantajları vardır. İlki, eğer bir işlem sistem çağrısı yaparsa, sadece bulunduğu işlemci o çağrıyla ilgilenebilir.
İkincisi, işlem-tabloları paylaşılamadığı için, işlemler işlemciler arasında paylaşılamaz. Mesela bir kullanıcı ikinci işlemcide sisteme giriş yaptıysa, bütün işlemleri giriş işleminden türeyeceği için, o kullanıcının işlemleri sadece ikinci işlemcide yürütülebilir. Üçüncüsü, bellek sayfaları paylaşılamadığından, bir işlemci sürekli eski sayfalar üzerine yazmak zorunda kalırken başka bir işlemcinin birçok boş sayfası olabilir. Son olarak da, arabellekler ayrı olduğundan, disk ile iletişim fazla olur ve arabellekten diske yazma/okuma işlemleri sırasında kararsızlıklar olabilir.
2) Birincil-ikincil çoklu işlemciler (Master-slave multiprocessors) İlk türün sorunlarından dolayı geliştirilmiştir. İşletim sistemi sadece bir işlemci üzerinde çalışır ve bu birincil (master) işlemcidir. Birincil işlemci işlemleri ikincil (slave) işlemciler arasında paylaştırır. Bir işlemci meşgul olduğunda işlem ondan alınıp başka boş olan bir işlemciye atanabilir. Arabellek, sayfalama ve işlem paylaşımı sorunları burada çözülmüştür; fakat bu çoklu işlemci işletim sisteminin sorunu da, bir ikincil işlemci sistem çağrısı yaptığında bununla sadece birincil işlemcinin uğraşabilmesidir. Her işlemcinin zamanının yüzde onunu sistem çağrısı yaparak geçirdiği düşünüldüğünde birincil işlemci büyük bir darboğaz olur. Bu yüzden bu model küçük çoklu işlemciler için kullanılabilir.
3) Simetrik çoklu işlemciler (Symmetric multiprocessors) SMP modeli birincideki asimetrik işletim sistemi yürütülmesini simetrik hale getirir, yani ortak bir işletim sistemi bütün işlemcilerde çalıştırılabilir. Her işlemci işletim sisteminin bellekte duran kopyasını çalıştırabilir, böylece deminki modeldeki gibi bir darboğaz yaşanmaz. Sayfalama ve arabellek sorunları zaten çözüldüğünden, geriye sadece bir sorun kalır: senkronizasyon. Birden fazla işlemci işletim sistemi verilerine ulaşmaya ve hatta değiştirmeye çalıştığında, senkronizasyon yapılmazsa bu model tamamen çöker. Mesela, işletim sistemi işlem tablosundaki çalışmaya hazır programlar listesini ele alalım. Ya iki işlemci aynı anda gelip bu listedeki ilk programı alıp çalıştırmaya çalışırsa? Veya boş görünen bir sayfayı iki işlemci aynı anda kullanmaya çalışırsa? Bu gibi zamanlama sorunlarına getirilen çözüm tüm işletim sistemini bir kritik bölge gibi görerek, sistem çağrılarına kilit koymak. Böylece bir işlemci işletim sisteminin kilidini ancak içeride başka bir işlemci yoksa alabilir. Ancak bu da bir önceki modelle aynı soruna sahip, belli bir anda sadece bir işlemci aktif olabilir. Ama bunu aşmak da kolay. İşletim sisteminin çoğu bölümü birbirinden bağımsız veri yapıları sahip ve farklı işlemcilerin bu farklı bölümlerde çalışması hiçbir sorun yaratmaz. Mesela bir işlemci zamanlayıcıyla işlemleri listelerken, diğer bir işlemci dosya sistemiyle ilgili bir çağrıya bakabilir. İşletim sistemi böyle bağımsız parçalara ayrılıp her parçaya kendi kilidini sağlandığında, işletim sisteminin içinde aynı anda birden çok işlemci aktif olabilir. Böyle bir işletim sisteminde, işletim sistemi kodunu yazmak değil, işletim sistemini parçalara ayırıp kilitleri ayarlamak zor. Çünkü bağımsız işlemler olduğu gibi, aynı veri yapılarını kullanan işlemler de var ve önlem alınmazsa bunların farklı işlemciler tarafından beklenmesi ölümcül kilitlenmeye (deadlock) yol açar.
İşletim sistemleri açısından çoklu işlemciler birçok işlemde farklılık gösterir. Senkronizasyon, zaman-programlama, alan paylaşma ve buna benzer bir çok işletim sistemi işlevi ayrıntısına bu yazıda girmiyorum. Hayatımıza neredeyse daha yeni giren çoklu işlemcilerin gelişimi bakalım teknolojinin hızıyla daha nasıl değişecek. Umarım bir parça olsun çoklu işlemciler hakkında merak ettiklerinizin cevabını yazımızda bulabilmişsinizdir. Yeni sayılarımızda görüşmek dileğiyle, hoşçakalın sevgili e-bergi okuyucuları :)
Kaynaklar:
- Modern Operating Systems, Andrew S. Tanenbaum, 2001, Second Edition
- http://kovan.ceng.metu.edu.tr/~erol/Courses/CENG334/documents/CENG334-2008-W15a-multiple-processors.ppt
- http://www.cs.fiu.edu/~sadjadi/Teaching/Operating%20Systems/Lectures/Chapter-08.ppt