Bir Mahrumiyetin Sonu

Geçenlerde genç bir yazılımcı arkadaşımızdan bir mail aldım. Şöyle yazmış:

int MAX_SOCK_NUM=4;
for(int sock=0; sock < MAX_SOCK_NUM; sock++){
...
}
&#91;/sourcecode&#93;

<span id="more-358"></span>

<i>4 için int yapmanın anlamı ne? Bu kod Arduino açık kaynak kodu, sock değişkeni için neden short tipini seçmemişler? Bunları neden önemsemiyorlar?</i>


Yazıma devam etmeden, arkadaşımızın ne demek istediğine açıklama getirmek istiyorum. Int genelde 32 bitlik bir veri tipidir, yani unsigned bir int ile 0 - 4294967295 (4.3 milyar) arasında bir rakamı adresleyebiliriz. Eğer bir biti negatif rakamları da tutmak için ayıracak olursak, int veri tipindeki bir değişkende +- 2.1 milyarlık bir rakamı tutabiliriz.


Yukarıda yer alan kod örneğinde 4 rakamını tutabilmek için int veri tipinde olan ve MAX_SOCK_NUM ismini taşıyan bir değişken oluşturulmuş. Bu kod Arduino gibi bir mikro denetleyici bünyesinde koşturulduğunda, bu değişkenin işgal ettiği bellek miktarı aşağıdaki şekilde olacaktır:

<img src="http://www.mikrodevre.com/wp-content/uploads/2015/01/atmega1.png">

Koddan anlaşıldığı gibi, uygulamanın ihtiyacı olan değişkenin büyüklüğü 4 rakamını temsil edebilecek bir bit kombinasyonudur. Bu bit kombinasyonu bir byte olarak şu şekilde yazabiliriz:


00000100

Eğer ihtiyacımız tek bir byte ise, bu durumda değişken için gerekli bellek alanı şu şekilde olacaktır:

Byte veri tipi ile bir rakamı temsil etmek mümkün olmadığı için bir yüksek veri tipi olan short veri tipini kullanabiliriz. Short 16 bit uzunluğunda olup, 0-65535 arası bir rakamı temsil edebilmektedir ki bu da bizim işimizi görmektedir. Sonuç itibari ile değişken bünyesinde tutmak istediğimiz değer 4 rakamıdır.

Bu kadar laf salatasına ne gerek var, ha int, ha short, ne fark eder diyebilirsiniz. Arada çok ince bir fark var. Bunu anlatmaya çalışacağım. Bu fark bizim yazılımcı olarak donanıma ne kadar uzak ya da yakın olduğumuzu gösteriyor.

Buradaki yazimda ifade etmeye çalıştım. Biz yazımcılar ne yazık ki donanımdan çok uzaklaştık. Bunun çok çeşitli sebepleri var. Başlıca sebebi donanımcıların son yıllarda baş döndürücü hızda donanımda kat ettikleri yol ve biz programcıların her şeyi soyutlama merakı. Soyutlaya, soyutlaya öyle bir seviyeye geldik ki, artık en altta, yani mikro işlemci bünyesinde olup bitenlerden bihaberiz. Bunun en güzel örneğini yazımın başında verdiğim kod örneği teşkil ediyor. Programcının birisi kısıtlı bellek alanına sahip olan bir mikro denetleyici için short veri tipini kullanması gerekirken, int veri tipini kullanmış ve en az 2 byte genişlikteki bellek alanını kullanılmaz hale getirmiştir.

İsterseniz burada ufak bir analiz yapalım. Programcı muhtemelen 32/64 bitlik mikro işlemciler için kod yazmaktadır. Aynı programcı 8 bitlik bir mikro denetleyici için kod yazmaya başladığında 32/64 bitlik kod yazma alışkanlıklarına devam etmekte ve kod yazdığı donanımın sahip olduğu özellikleri göz ardı etmektedir. Eğer kullandığı donanımın yapısal özelliklerini göz önünde bulundursaydı, gerekli değişkeni şu şekilde tanımlardı:

short MAX_SOCK_NUM=4; 

Bu bence donanımdan kopmuşluğun en belirgin ibaresidir. Ben buna en çok Java dünyasında rastlıyorum. Java sanal makinesinin var oluşu (JVM) ve yazılan Java kodunun her platformda koşturulabilir olması, Java programcılarını tamimiyle donanımdan koparmış ve matrixde yaşayan programcılar haline getirmiştir.

“Ben programcıyım, donanımla ilgilenmem” yaklaşımını doğru bulmuyorum. Ne için kod yazdığımızı bilmemiz gerekir. Soyutluk seviyesi yükseldikçe ne yazık ki donanımdan biraz daha uzaklaşıyor ve kaportanın altında ne olup bittiğini bile kestiremez hale geliyoruz. Bu gidişatı değiştirmek o kadar kolay değil, çünkü mikro işlemci tasarımcıları hız sınırına yaklaştıklarını anladıkları için artık hücre bölünme yöntemiyle donanım geliştirmeye başladılar. Çok kısa bir zaman sonra 512 ve 1024 çekirdekli mikro işlemciler için kod yazmak zorunda kalacağız. Cumanın gelişi perşembeden belli değil midir?

Bence burada bir mahrumiyet söz konusu. Donanımdan ve donanımı anlamaktan mahrum kaldık ya da edildik. Bilgisayarın başına oturduğumuz zaman sadece Eclipse ya da başka bir IDEyi görüyoruz, başka bir şey bizi ilgilendirmiyor. Kod yazıyoruz, nasıl çalıştığını anlamıyoruz. Ama kanımca artık bu mahrumiyetin sonu geldi.

Dünyada olup, biten olumsuzlukları göz ardı edebilecek olursak, teknik anlamda öyle muazzam, öyle güzel bir çağda yaşıyoruz ki, bu güzelliği kelimelerle anlatmam mümkün değil. Yazılımcı olarak donanıma yaklaşma ya da geri dönme kapıları bize açılmış durumda. Artık bir yazılımcı açışından donanım ve yazılıma eş değerde hakimiyetin mümkün olacağı çağda yaşıyoruz. Bunun bir örneği aşağıda yer alıyor.

Bu bir mikro denetleyici. 120 MHZ hızında ve 256KB bellek ve 1024KB flash bellek ihtiva ediyor. Biliyorum! Taş devrinde gibi hissettiniz kendinizi. Benim 20 sene önceki 386DX bilgisayarım bile bundan hızlıydı ve daha fazla belleği vardı. Ama mevzu bu değil.

Burada gördükleriniz, donanım ile ilgilenen ve donanım dünyasında giriş yapmak isteyen yazılımcılar için giriş biletleri. Bakın bunlarda var:


Arduino


Raspberry PI

Günümüzde popüler olmaya başlayan bazı mikro denetleyici ve mikro işlemcilerden örnekler vermeye çalıştım. Bu avuç içine sığacak büyüklükteki donanımlar için Java, C ve Assembly gibi dillerde program yazmak mümkün. Bu tür donanım için kod yazan programcılar donanıma çok yakın bir seviyede çalışıyorlar ve işlemcilerin bünyesinde olup, bitenleri daha iyi kavrayabiliyorlar. Bu onların daha iyi programcı olmalarını sağlıyor.

Programcılıkta daha derin bir anlayış seviyesine gelebilmek için donanıma yaklaşmanın, onun nasıl işlediğini anlamanın önemli bir rol oynadığını düşünenlerdenim. Programcılar donanımdan uzaklaşarak değil, ona yaklaşarak 512, 1024 ya da 2048 çekirdekli sistemler için paralel koşturulabilen uygulamalar geliştirebilirler.

Tarihte yeni bir dönemin başındayız. Bizi teknolojik açıdan çok güzel gelişmeler bekliyor. Bu gelişmelerin bir parçası olabilirsiniz.


EOF (End Of Fun)
Özcan Acar

10,386 toplam, 3 bugün içinde gösterim

Programlama kategorisindeki diğer yazılar:

Share Button
1 Yıldız2 Yıldız3 Yıldız4 Yıldız5 Yıldız (1 değerlendirme, ortalama: 5, toplam oy 5)
Loading ... Loading ...

Bir Mahrumiyetin Sonu” üzerine 10 düşünce

  1. Çok güzel bir yazı, benim sormak istediğim Arduino kodu diye bahsettiğiniz kod Arduino’da ki temel kodlardan mı? Eğer öyleyse bunu üretenler bu ince ve bir o kadar da önemli konuda neden böyle yapmışlar?

  2. Hocam yine güzel bir yazı olmuş eline sağlık. Sen illa bilgisayarcıları bizim alana sokacaksın bu gidişle 🙂 İşin şakası bir yana önemli konular bunlar.
    Aslında C ile kod yazarken int short gibi tipler yerine uint16_t , uint8_t, int32_t vs… gibi tanımlanmış tipleri kullanmak daha sağlıklı olabilir. Dolayısıyla değişik platformlara geçişlerde programlarda ortaya çıkabilecek hatalar da en aza indirilmiş olacaktır.
    C taşınabilir bir dil denilse de aslında platformlar arasında bir standart yok. Birinde int 32 bit iken diğerinde 16 bit olabiliyor.

      • Hocam elinize sağlık. Üstteki yoruma tamamen katılmakla birlikte char değişkeninin de sayılar için kullanılabildiğini eklemek isterim. Sadece – donanıma bağlı olarak – kullanabileceğiniz bit sayısı değişir. Char bir değişkeni C’de ++ ile artırabilirsiniz. Printf içerisinde de %d ile ekrana yazdırmanız durumunda sayısal değeri yazılacaktır.

  3. Çok beğendim yazınızı.Bilgisayar Mühendisliği Öğrencisi olarak ben de sizin gibi bir programcının donanımda olup bitenleri görmesi gerektiğini düşünüyorum..Teşekkürler.

  4. Oncelikle yazi icin tesekkurler, yaziyi gorunce bir iki not da ben eklemek istedim:

    4 degerini tutmak icin C’de “char” tipi de kullanilabilir. Char ile rakam tutmakta sorun yok.

    for loop icerisinde kullanilan “sock” degiskeni sadece loop icerisinde gecerlidir, yani sinirli bir scope da tanimli. Local degisken oldugu icin stack’ten allocate edilecek ve loop sona erdiginde temizlenecektir. Kisa sureli kullanimlar icin memory optimisation cok da gerekli olmayabilir. Yada ben olsam yapmazdim diyeyim.

    En son olarak da, short yada char yerine int kullanmak daha performansli olabilir, evet olabilir 🙂 Tabiki cok fazla kullanilan architecture ve compiler’a bagli. Ama genel olarak integer degerlerin register boyundaki tiplerde kullanilmasi tercih edilir. Performans kaybinin sebebi, data herzaman word size kadar memory’den yada cache’den cekilir. Yani siz char bile tanimlamis olsaniz datayi 4 byte olarak cekersiniz. Datayi 1byte’a cevirmek icin extra instructionlar eklemeniz gerekebilir ki bu da peformas kaybidir. Ayrica matematiksel islemlerde, register 4 byte oldugu icin benzer sekilde, char kullanirsaniz ekstra instructionlar eklenebilir. Burdaki performans kaybi cok kucuk, ve cok alt seviyede hardware limitations’dan kaynakli, cok dert etmeye degmez. Fakat alternatifindeki memory kazanci da ayni sekilde cok kucuk, ve eger dar bir scope’da ve stack sorununuz yoksa tam bir kazanciniz bile yok. Ben olsam int tipini kullanmaya dever ederdim, unless kullandiginiz architecture icin assembler kodlarini inceleyip bir performans kaybi soz konusu degil ise.

Yoruma kapalı.