Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Sefer Algan
Sefer Algan
http://www.seferalgan.com
İletişme geçmek için tıklayın.
71 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler:  C# / VC#/.NET Sefer Algan
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Başlangıç
Kategori : C# / VC#/.NET
Yayınlanma Tarihi : 30.11.2003
Okunma Sayısı : 36700
Yorum Sayısı : 4     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 4.10.2024
Turhal Temizer
Mac OS/X Removing CUDA 4.10.2024
Burak Selim Şenyurt
Rust, WASM, Web Api ve Can-Ban Board ! 4.10.2024
Burak Selim Şenyurt
Kurumsal Yazılımcının Oyun Geliştirme ile İmtihanı 4.10.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
Kod Optimizasyonu ve "volatile" Anahtar Sözcüğü
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
Bu yazıda C#'ın önemli ama tam olarak neden kullanıldığı bazı profesyonel programcılar tarafından bile pek fazla bilinmeyen bir anahtar sözcük olan volatile üzerinde duracağız.

Bir çok popüler derleyici sizin isteğiniz dışında kodunuzun işleyiş mantığına müdahale edebilmektedir. Bu müdahalenin en bilinen sebeplerinden birisi uygulumanızın kod boyutunu küçültmek yada uygulamanızın çalışma zamanını düşürmektir. Aslında biz bu işlemlerin tamamına birden optimizasyon da diyebiliriz. Zira hemen hemen bütün derleyicilerin optimizasyon işleminin yapılıp yapılmayacağını belirten bir parametresi vardır. C# derleyicisi için bu parametre /optimize yada kısaca /o şeklindedir.

Peki optimizastondan neyi anlamalıyız? Genel olarak iki farklı şekilde optimizasyondan bahsetmek mümkündür. Birincisi daha henüz derleme aşamasındayken programcının gözünden kaçan bazı gereksiz bildirimlerin veya tanımlamaların derleyici tarafından derlenecek koda dahil edilmemesi ile olabilir. Örneğin hiç kullanmadığınız bir değişken için bellekte bir alan tahsis edilmesinin hiç bir gereği yoktur. Bu yüzden hiç bir yerde kullanılmayan değişkenlerin derleyiciniz tarafından derleme modülüne iletilmemesi bir optimizasyon olarak görülmektedir. Bu tip optimizasyon kapsamı içinde ele alınabilecek diğer bir örnek ise aşağıdaki kod parçası ile gösterilmiştir.

Not : Aşağıdaki kodun bilinçsiz yada dalgın bir programcı tarafından yazıldğını varsayıyoruz.

int a = 0;

while(a != 0)
{
     a = 2 ;
     a = 0 ;
}


Yukarıdaki kodda akış hiç bir zaman while bloğunun içine gelmeyecektir. Ve üstelik eğer a değişkeni farklı bir iş parçacığı(thread) tarafından while bloğuna girmeden değiştirilip akış while bloğuna girse bile a değişkeni while bloğu içinde tekrar eski sabit değerine atanıyor. Dolayısıyla while bloğunda bulunan kodların çalıştırılabilir uygulama dosyasının boyutunu büyütmekten başka bir işe yaramayacağı açıktır. O halde burda insan üstü bir mekanizmanın devreye girip kodu optimize etmesi gerekir. Bu mekanizma elbetteki derleyicinin optimizasyon işine yarayan parametresidir. Optimizasyon işleminde derleyiciden derleyiciye fark olmasına rağmen yukarıdaki kod parçasının geebileceği en optimum biçim aşağıda gösterildiği gibidir.

int a = 0;

while(a != 0)
{

}


Diğer bir optimizasyon biçimi ise derleyicinin değişkenlerin elde edilmesinde yada tekrar yazılmasında belleğin yada işlemcinin tercih edilmesi ile ilgilidir. Bu noktada mikroişlemciler ile ilgili kısa bir bilgi vermekte fayda var : Kaynak kodumuz çalıştırılabilir durumdayken aslında makine koduna çevrilmiştir. Bu komutlar daha önceden mikroişlemcilerde elektronik düzeyde programlandıkları için bu komutlar tek tek mikroişlemcide kolaylıkla icra edilir. Mikroişlemciler aynı anda tek bir iş yapabileceği için yapacağı işlemler içinde kullandığı değişkenleri her defasında bellekten almak yerine daha hızlı olması açısından mikroişlemcideki data register dediğimiz kayıtçılarda tutar. Bu register dediğimiz bölümlerin sınırlı sayıda bulunduğunu belirtmek gerekir. Dolayısıyla bellekte bulunan uygulamamızın ihtiyacına göre daha doğrusu icra edilecek bir sonraki makine kodunun çeşidine göre işlemci bellekten ilgili değişkenleri register'larına yükler ve ilgili komutunu çalıştırır. Doğaldır ki bir değerin mikroişlemci tarafından belleğe(ram) yazılması ile mikroişlemcideki register bölgesine yazılması arasında dağlar kadar fark vardır. Bu fark elbette hız faktörüdür. İşte tam bu noktada ikinci tip optimizasyon kuralını tanımlayabiliriz. Derleyici öyle bloklara rastlayabilir ki, bu bloklar içinde bulunan bir değişkenin değerini her defasında bellekten okuyacağına bu değişkenin değerini bir defaya mahsus olmak üzere mikroişlemcinin ilgili register bölgesine bölgesine kaydeder ve sonraki okumalarda işlemci bellek yerine bu register bölgesini kullanır. Böylece kodunuzun çalışma süresinde önemli sayılabilecek bir azalma görülür. Elbetteki bu optimizasyon işleminin yüzlerce kez tekrarlandığını varsayarak bu sonuca varıyoruz.

Yukarıda değişken okuma ile ilgili söylediklerimin aynısı bir değişkenin değerini değiştirmek için de geçerli olduğunu belirtmeliyim. Yani siz programınızın 10. satırında bir değişkenin değerini bir değerden başka bir değer çektiğiniz halde derleyici bu işlemi 15.satırda yapabilir. Bu durumda 15. satıra kadar o değişkenin kullanılmadığı yorumunu yapabiliriz. Bu şekilde mikroişlemcinin belleğe yazma işlemi geciktirilerek belli ölçüde optimizasyon sağlanır. Tabi bu optimizasyonun ölçüsü tamamen mikroişlemcinin o anki durumuna bağlıdır.

Buraya kadar herşey normal. Bir de madolyonun öteki yüzüne bakalım. Bildiğiniz üzere uygulamalar genellikle çoklu iş parçacıklarından(multi thread) ve proseslerden oluşur. Her bir proses diğer bir proses teki değişkene işletim sisteminin izin verdiği ölçüde erişip üzerinde işlemler yapabilir. Aynı şekilde bir iş parçacığıda diğer bir iş parçacığında bulunan değişkene erişip üzerinde çeşitli işlemler yapabilir. Peki bunun bizim optimizasyon kurllarımızla bağlantısı ne? Şöyle ki : derleyici bir değişkenin değerinin farklı bir iş parçacağı tarafından yada farklı bir proses tarafından işleneceği üzerinde durmaz. Bu tamamen işletim sisteminin yönetimindedir. Hal böyleyken bizim yukarıda bahsettiğimiz ikinci optimizasyon tipi bazı durumlarda yarar getireceğiniz zarar getirebilir. Zira optimizasyon adına bir değişkenin değerini her defasında bellekten okuma yerine mikroişlemcideki ilgili register dan okurken o anda farklı bir iş parçacağı yada farklı bir proses hatta ve hatta işletim sistemi sizin erişmeye çalıştığınız değişkenin değerini sizin uygulamanızın mantığına göre değiştirebilir. Bu durumda siz o değişkenin son halini kullanmamış olursunuz. Dolayısıyla programınızda farklı thread lar yada prosesler arasında paylaşılan veya işletim sistemi tarafından değiştirilmesi muhtemel olan değişkenlerinizi optimizasyon kuralına tabi tutmamanız gerekir. Peki bunu nasıl başaracağız?

volatile anahtar sözcüğü burada imdadımıza yetişiyor. Bir değişkeni volatile anahtar sözcüğü ile bildirdiğiniz takdirde derleyicinizin optimizasyon ile ilgili parametresini açık tutsanız bile ilgili değişken yukarıda bahsi geçen tehlikeli optimizasyon kurallarına tabi tutulmayacaktır. Yani volatile ile bildirilen değişkenlere programın akışı sırasında her ihtiyaç duyulduğunda değişkenin gerçek yeri olan belleğe başvurulur. Aynı şekilde bir değişkene yeni bir değer yazılacağı zaman bu yazma işlemi hiç geciktirilmeden bellekteki yerine yazılır. Böylece volatile ile bildirilen değişkenler farklı iş parçacıkları yada prosesler tarafından ortak kullanılıyor olsada programın akışı içerisinde her zaman son versiyonu elde edilecektir. Çünkü bu değişkenlerin değeri her defasında bellekten çekilir. Her ne kadar optimizasyondan taviz verme zorunda kalsak ta böylece uygulamalarımızda çıkabilecek olası bugların(böcek) önüne geçmiş oluruz.

volatile, C# dilindeki anahtar sözcüklerden biridir. Üye değişken bildirimi ile birlikte kullanılır. volatile anahtar sözcüğü yalnızca aşağıdaki değişken tipleri ile birlikte kullanılabilir.

  • Herhangi bir referans tipindeki değişken ile

  • byte, sbyte, short, ushort, int, uint, char, float yada bool. türünden olan değişkenler ile

  • byte, sbyte, short, ushort, int, yada uint türünden semboller içeren numaralandırmalar(enums) ile

  • unsafe modda iken herhangi bir gösterici türü ile
volatile anahtar sözcüğünün kullanımına bazı örnekler verelim :


public static volatile int a;

public volatile bool a;

public volatile int* a;

....

Microsoft'un resmi dökümanlarında(MSDN) verilen bir örneği buraya taşıyarak ne gibi durumlarda volatile anahtar sözcüğüne ihtiyaç duyacabileceğimizi görelim.

using System;
using System.Threading;

class Test
{
    public static int result;
    public static volatile bool finished;

    static void Thread2()
    {
        result = 143;
        finished = true;
    }

    static void Main()
    {
        finished = false;
        new Thread(new ThreadStart(Thread2)).Start();

        for (;;)
        {
            if (finished)
            {
                Console.WriteLine("result = {0}", result);
                return;
            }
        }
    }
}

Yukarıdaki örnek programdaki püf nokta finished isimli değişkenin ana thread ve ana thread içinde başlatılan yeni thread tarafından ortak kullanılan bir değişken olmasıdır. Eğer finished değişkeni volatile olarak bildirilmemiş olsaydı, akış thread2 metoduna gelmiş olmasına rağmen Main metodu içindeki if bloğu çalıştırılmayabilirdi. Çünkü derleyici ana thread içinden finished değişkeninine tampolanmış bir bölgeden(register) erişebilir. Bu durumda finished değişkeninin gerçek değeri true olmasına rağmen ana thread de finished değişkeni halen false olarak ele alınır. Bu yüzden finished değişkeninin her durumda son versiyonunu elde etmek için bu değişken volatile anahtar sözcüğü ile bildirilmiştir.

volatile anahtar sözcüğünün kullanımına bir örnek daha verelim. Belli bir anda bir sınıftan sadece bir nesnenin oluşmasını sağlayan Singleton desenini daha önceki bir makalemde ele almıştım. Bu konu ile ilgili bilgi eksikliğiniz varsa ilgili makaleyi okumanızı tavsiye ederim. Bahsi geçen makalede verilen desenin bir uygulaması aşağıda ki gibi yeniden yazılmıştır.

public class SingletonDeseni
{
     private static volatile SingletonDeseni nesne; 

     private static Object kanalKontrol = new Object; 

     private SingletonDeseni() 
     {

     } 

     public static Singleton Nesne()
     { 
         if(nesne == null)
         {
              lock(kanalKontrol)
              {
                    if(nesne == null)
                   {
                           nesne = new SingletonDeseni();
                   }
              }
         }

          return nesne; 
     }
}

Bu örnekte SingletonDeseni nesnesinin belli bir anda tekil olarak bulunduğunu çok kanallı uygulamalar içinde geçerli kılmak için bu nesne volatile olarak bildirilmiştir. Üstelik bu örnekte farklı bir prosesin müdahalesi olsa bile bu nesneden ancak ve ancak bir adet yaratılacaktır.

Son olarak volatile kelimesinin sözlük anlamı üzerinde durmak istiyorum. İki yıl önce İngilizce'den Türkçe'ye çevrilmiş bir Visual C++ kitabını okuduğumda volatile ile bildirilmiş değişkenlerden oynak(!) değişkenler diye bahsedildiğine şahit oldum. İlk başta bu ilginç kullanım bana birşey ifade etmedi ama hislerimin yardımıyla aslında yazarın volatile dan bahsettiğine karar verdim. Sizde takdir edersiniz ki yukarıda anlattıklarımız ile "oynak" kelimesi arasında pek bir bağ bulunmamaktadır. Kitabın çevirisini yapan yazar muhtemelen bir programcı değil bir çevirmendi. Çünkü eğer iyi bir programcı olsaydı oynak kelimesi yerine daha uygun bir kelime seçilebilirdi. volatile'ın sözlük anlamı "uçucu olan", "buhar olan" anlamına gelmektedir. Ancak ben henüz volatile sözcüğüne kendi mesleğimizle ilgili uygun bir karşılık bulamadım. Bu konuda daha önce cdili ve cdernek isimli iki yahoo grubunda çeşitli tartışmalar olmuştur. Bu gruplara üye olarak ilgili tartışmalarda geçen konuşmaları okumanızı öneririm. Eğer sizin de bu konuda önerileriniz varsa bizimle paylaşırsanız seviniriz.

Umarım faydalı bir yazı olmuştur. Herkese iyi çalışmalar...

Makale:
Kod Optimizasyonu ve "volatile" Anahtar Sözcüğü C#, Visual C# ve .NET Sefer Algan
  • Yazılan Yorumlar
  • Yorum Yaz
TEM
15
2009
volatile optimizasyonda ayrıcalıklı bir durumu belirttiği için türkçesi olarak ayrıcalıklı, istisnai, dokunulmaz, optimizasyondanmuaf diyebilir miyiz. Yada daha isabetli olsun diye bellektekiyerideğiştirilemez, bellektekiyerisabit olabilir mi. yada kısaltarak yerideğiştirilemez, yerisabit ?
ARA
1
2003
ilginize teşekkürler...
ARA
1
2003
C# ile ilgili standart ifadelerin ötesinde, yazılımcılara vizyon kazandıracak teknikleri ve biraz da işin felsefesini içeren bu tip yazılarınızın sürekli olmasını diliyorum. Elinize, kafanıza sağlık.
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor