<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3116305503626125655</id><updated>2012-02-17T06:22:33.664+02:00</updated><category term='lkd_gezegen'/><title type='text'>Özgür Murat Homurlu</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ozgurmurat.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3116305503626125655/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ozgurmurat.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Özgür Murat Homurlu</name><uri>http://www.blogger.com/profile/12974133656426552616</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3116305503626125655.post-1295645701445935185</id><published>2009-05-23T15:34:00.018+03:00</published><updated>2009-11-25T00:18:50.160+02:00</updated><title type='text'>C Dilinde Volatile Anahtar Kelimesi</title><content type='html'>&lt;h4&gt;C Dilinde Volatile Nedir&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Volatile anahtar kelimesi derleyicinin volatile olarak tanımlanan alana (değişken, bellek alanı, struct alanı vb.) yapılan yazma ve okumaları optimize etmemesinin istendiğini belirtir. Optimizasyon kod boyutu ve hız üzerinde önemli bir etkiye sahip olduğu için hata ayıklama süreci dışında her zaman istenilen bir özelliktir. Optimizasyon tekniklerinden bir tanesi, derleyicinin değişkenler ve alanlara yapılan yazma ve okumalardan gereksiz olanlar için kod üretmemesi ve bu işlemleri uygun gördüğü gibi sonucu değiştirmeyecek şekilde yeniden sıralamasıdır (mesela pipeline'ı verimli kullanmak için). Örneğin bir değişkenin değeri bir register'ın içerisine okunduysa programda aynı değişkenin tekrar değerini okumayı gerektiren bir durumda okuma işlemi yeniden yapılmaz ve register'daki hazır değer kullanılır. Yazma durumu da derleyicinin uygun gördüğü bir ana kadar ertelenebilir veya tekrar aynı değerin yazıldığı tespit edilebiliyorsa yazma işlemi bir kez yapılacak şekilde kod üretebilir. Normal durumlarda bu hızlandırma tekniklerini istesek de aşağıda belirilen amaçlarla bazı alanların programda belirtildiği anlarda ve sırada yeniden okuma/yazma yapılmasına gerek duyarız.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Volatile Nerelerde Kullanılır&lt;/h4&gt;&lt;br /&gt;Gelenekse olarak volatile'ın kullanılmasını gerektiren durumları aşağıda listeledim. Neden volatile'ın modern mimarilerde yetersiz kaldığını öğrenmek için ise okumaya devam edin.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Interrupt servis rutinleri içerisinde değiştirilen bir alan kesme dışındaki kodda okunuyorsa (ya da tam tersi) söz konusu alanın değeri programın çalışması süresince her an değişebilir. Derleyici bundan haberdar olmadığı için bir kere değeri okuyup/yazdıktan sonra tekrar aynı işlemi yapmayabilir. Bu tip alanların bu yüzden volatile olarak tanımlanması gerekir (ve haliyle atomik olarak okunup/yazılabilmesi gerekir).&lt;/li&gt;&lt;li&gt;Unix/POSIX signal handlerlar interruptlara benzerler: keyfi bir anda akışı kesebilirler. Bu yüzden handler içinden çağırdığınız fonksiyonların en azından reenterant olması gerekir ve handler içerisinde blocking bir çağrı yapamazsınız. Interrupt servis rutinlerinde olduğu gibi handler içerisinde ve kodda paylaşılan alanların volatile olarak tanımlanması gerekir.&lt;/li&gt;&lt;li&gt;Memory mapped IO için söz konusu hafıza alanının volatile olarak tanımlanması gerekir. Hafıza olarak görülen alan aslında donanım registerına veya örneğin donanım üzerindeki belleğe karşılık geldiği için okuma ve yazma her zaman programda istenildiği yerde ve istenen sayıda yapılmalıdır.&lt;/li&gt;&lt;li&gt;Multithread programlamada doğrudan paylaşılan (örneğin mutex ile kritik bölge içerisinden erişilmeyip doğal haliyle atomik olarak  olarak okunup yazılan) bir alanın da volatile olarak tanımlanması gerekir.&lt;/li&gt;&lt;li&gt;C standart kütüphanesindeki setjmp/longjmp komutlarının kullandıldığı durumlarda setjmp çağrıldıktan sonra değiştirilen alanların longjmp çağrıldıktan sonra değerleri undefined olacaktır. Volatile olarak tanımlanmaları halinde son değerlerini korurlar.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Örnek&lt;/h4&gt;&lt;br /&gt;Aşağıdaki C kodunu "gcc -O -S volatile.c" komutu ile derleyeceğiz:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;volatile int g_val = 42;&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt;int f;&lt;br /&gt;f = g_val;&lt;br /&gt;f = g_val;&lt;br /&gt;f = g_val;&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Kodda dikkat çeken nokta, global değişkeni okuyarak değeri f değişkenine yazıyoruz, ancak f değişkenindeki değer hiç kullanılmıyor. Volatile anahtar kelimesini &lt;b&gt;silersek&lt;/b&gt; derleyicinin main fonksiyonu için ürettiği kod şu:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;main:&lt;br /&gt;mov     r0, #0&lt;br /&gt;bx      lr&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Yani sadece 0 değerini döndüren (return 0) ve başka bir iş yapmayan bir fonksiyon. Derleyici optimizasyon yaptı ve hiç bir işe yaramadığını tespit ettiği işlemler için komut üretmedi.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Şimdi de volatile anahtar kelimesi varken derleyelim:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;main:&lt;br /&gt;ldr     r3, g_val&lt;br /&gt;ldr     r2, [r3, #0]&lt;br /&gt;ldr     r2, [r3, #0]&lt;br /&gt;ldr     r3, [r3, #0]&lt;br /&gt;mov     r0, #0&lt;br /&gt;bx      lr&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Bu kez volatile ile optimizasyonu engellediğimiz için üç ldr komutu ile üç kez g_val'ın gösterdiği adresten okuma yapıldı. &lt;br /&gt;&lt;p&gt;&lt;br /&gt;Bu durumda okuma işlemleri hiç bir işe yaramıyor görünüyor ama g_val'ın bir donanım registerını gösterdiğini düşünelim. Donanım register'ları normal hafızadan farklı davranışlar gösterebilirler. Örneğin sadece okuma işlemi bile donanımın durumunda bir değişiklik yaratabilir.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Volatile'ın Modern Mimarilerdeki Yetersizliği&lt;/h4&gt;&lt;br /&gt;Yazdığımız programın modern çok işlemcili mimarilerde optimizasyon ve mimari nedeniyle tam olarak yazdığımız gibi çalışmamasının ana nedenleri şunlar. 1. Derleyici komutların sıralarını ve okuma yazma işlemlerini değiştirebilir 2. işlemci komutların çalışma  sıralarını değiştirebilir 3. Bir işlemcinin hafızaya yazdığı değer önbelleğinde kaldığı için o anda farklı bir işlemci tarafından görülemez ve eski değer okunur (visibility). Volatile kelimesi sadece 1 numaralı optimizasyonu engeller ancak standart diğer durumlardan bahsetmez. gcc bu yüzden kendisinden istenilenden fazlasını yapmaz ve volatile kullanılsa da 2 ve 3 numaraları sorunlar devam eder.&lt;br /&gt;Çözüm işlemcilerin "memory barrier" olarak isimlendirilen komutlarını kullanmaktır. Bu komutlar ön belleği boşaltır ve okuma yazma işlemlerini sıralar. Ancak C kodu içerisinde bunları çağırmanın doğrudan bir yolu yoktur ve bu güzel bir çözüm de olmaz (çok düşük seviyeli). Not: Java dilindeki volatile kelimesi Java 5.0'dan beri memory barrier komutlarını kullanır. &lt;br /&gt;&lt;p&gt;&lt;br /&gt;Uygulama seviyesinde sorunun çözümünü pthread kütüphanesi sağlar. Örneğin paylaşılan bir alana mutex ile koruduğumuz bir kritik bölge içinden eriştiğimizi düşünelim. Mutex'i kilitleyip açtığımız pthread çağrıları hem derleyici seviyesinde hem de işlemci seviyesinde (memory barrier komutları ile) gerekeni yapacaktır. Bu yüzden multithread programlama yaparken paylaşılan alanları volatile yapmak gerekmez ve &lt;b&gt;yetmez&lt;/b&gt;. Bunun yerine alana erişimi gerekli pthread ya da kullanılan daha üst seviyeli kütüphane çağrıları ile kontrol etmeliyiz.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Memory barrier'lerle ilgili güzel bir belge Linux kernel dokümantasyonu içerisinde geliyor. Bu dokümana göre desteklenen mimariler içerisinde bu konuda baz alınan mimari agresif optimizasyonları nedeniyle Alpha mimarisiymiş.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3116305503626125655-1295645701445935185?l=ozgurmurat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ozgurmurat.blogspot.com/feeds/1295645701445935185/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3116305503626125655&amp;postID=1295645701445935185' title='4 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3116305503626125655/posts/default/1295645701445935185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3116305503626125655/posts/default/1295645701445935185'/><link rel='alternate' type='text/html' href='http://ozgurmurat.blogspot.com/2009/05/c-dilinde-volatile-anahtar-kelimesi.html' title='C Dilinde Volatile Anahtar Kelimesi'/><author><name>Özgür Murat Homurlu</name><uri>http://www.blogger.com/profile/12974133656426552616</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3116305503626125655.post-4535204108838047419</id><published>2009-05-19T22:01:00.010+03:00</published><updated>2009-07-01T06:16:16.727+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lkd_gezegen'/><title type='text'>Assembly Dili</title><content type='html'>Linux çalıştıran ARM işlemcili bir cihazınız veya sanal makineniz varsa aşağıdaki kodu ".S" uzantılı bir dosyaya kaydedip "gcc -o hello dosya.S" komutu ile derleyebilir ve "./hello" komutu ile çalıştırabilirsiniz.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#include &amp;lt;syscall.h&amp;gt;                                       &lt;br /&gt;.text&lt;br /&gt;.global main&lt;br /&gt;main:&lt;br /&gt;   stmfd sp!, {r7, lr}&lt;br /&gt;   ldr r0, =hello_string&lt;br /&gt;   ldr r1, =strlen&lt;br /&gt;   blx r1&lt;br /&gt;   mov r2, r0&lt;br /&gt;   mov r0, #0&lt;br /&gt;   ldr r1, =hello_string&lt;br /&gt;   ldr r7, =__NR_write&lt;br /&gt;   svc 0&lt;br /&gt;   ldmfd sp!, {r7, lr}&lt;br /&gt;   mov r0, #0&lt;br /&gt;   bx lr&lt;br /&gt;&lt;br /&gt;hello_string:&lt;br /&gt;.string "Merhaba Dünya!\n"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Neden Assembly&lt;/h4&gt;&lt;br /&gt;Günümüzde Assembly ile programlama büyük ölçüde tarihe karışmış durumda. Sistem programlamada, o da belirli ve küçük rutinlerin yazılmasında (boot kodu, context değiştirme, işlemcinin hafıza yöneticisini programlama, atomik primitiflerin yazılması vb. gibi) kaçınılmaz olarak kullanılıyor. Assembly ile optimize edilen kodlar sadece işlemci hızının yetersiz olduğu gömülü sistemler veya işlemcinin ekstra özelliklerini (Intel işlemcilerdeki SIMD komutları gibi) kullanmanın gerekli olduğu yerlerde gündeme geliyor. Bu tür işlerle uğraşmıyorsanız da Assembly öğrenmenin sağlayacağı faydalar var:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; Assembly bilen birinin optimize C kodu yazmanın püf noktalarını öğrenmesi ve anlaması daha kolaydır.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;İşletim sistemi olmayan veya çok minimal bir işletim sistemi olan gömülü bir sistemle uğaşıyorsanız açlış rutininin ne yaptığı, işlemcinin çalışma modları gibi önemli bilgileri iyi anlamanın tek yolu işlemcinin Assembly dilini bilmekte yatıyor.&lt;/li&gt;&lt;br /&gt;&lt;li&gt; Sadece zevk veya daha iyi anlamak için. Assembly doğrudan işlemci üzerinde çalıştığı için yüksek seviyeli dillerden sonra ilginç ve öğretici bir deneyim sağlayabilir.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Neden ARM Assembly&lt;/h4&gt;&lt;br /&gt;Benim ARM Assembly öğrenme sebeplerim şunlar:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; Yaygın kullanılan 32-bit bir işlemcinin Assembly dilini öğrenmek istiyordum. ARM assembly hem basit hem de ilginç özelliklere sahip.&lt;/li&gt;&lt;br /&gt;&lt;li&gt; ARM7TDMI mimarili mikro kontrolcü üzerinde işletim sistemi olmadan veya sadece scheduler ve gerçek zamanlı programlama için gerekli temel yapıları (semaphore, message queue, priority inheritance mekanizmalı mutex) sağlayan FreeRTOS ile programlama yaptığımdan.&lt;/li&gt;&lt;br /&gt;&lt;li&gt; ARM mimarisi güç tüketimi açısından verimli olduğu için mobile uygulamalarda çok kullanılıyor (örneğin iPhone). İşin aslı sayı olarak dünyanın en çok satan işlemcisi ünvanına sahip. Cortex A8 ve A9 gibi versiyonları ile artık nispeten yüksek hızlara da erişmeye başladı. ARM tabanlı netbooklar belki başta biraz yavaş kalacaklar ama ileride ciddi bir pazar payına ulaşma ihtimali var.&lt;/li&gt;&lt;br /&gt;&lt;li&gt; Bu sayede "ARM System Developer's Guide" isimli nasıl optimize C kodu yazılacağından interrrupt servis rutini yazma metodlarına kadar değişen konuları ayrıntılı bir şekilde açıklayan bir kitabı okuyup anlamam mümkün oldu.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3116305503626125655-4535204108838047419?l=ozgurmurat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ozgurmurat.blogspot.com/feeds/4535204108838047419/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3116305503626125655&amp;postID=4535204108838047419' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3116305503626125655/posts/default/4535204108838047419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3116305503626125655/posts/default/4535204108838047419'/><link rel='alternate' type='text/html' href='http://ozgurmurat.blogspot.com/2009/06/assembly-dili.html' title='Assembly Dili'/><author><name>Özgür Murat Homurlu</name><uri>http://www.blogger.com/profile/12974133656426552616</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
