22.05.2012

Silverlight 3.0 ve GPU Kullanımı


Bazı yazılımsal işlemleri özel donanım desteği her zaman performansı arttırır. Aslında bunun çok basit bir nedeni var özünde. Yapacağımız yazılımsal işleve özel bir donanım kullanıyor olmanın yanı sıra özellikle bugün bilgisayarlarımızda normal şartlarda söz konusu işlemi yapmakla yükümlü birimi başka işlemler için serbest bırakıyor olmamız da önemli bir nokta. Neden mi bahsediyorum? Örneğin bilgisayarlarımızdaki ekran kartları! Hatırlayanlarınız vardır :) Eskiden oyunlardaki 3D hesaplamaları vs bilgisayarlarımızın normal işlemcileri üstlenirdi. Sonrasında ekran kartlarında GPU denilen bir birim ortaya çıktı ve 3D dahil birçok görsel hesaplamalayı işlemcilerimizin üzerinden aldı. Böylece hem işlemcilerimiz rahatladı :) diğer işlemler ile çok daha rahat ilgilenir oldular hem de söz konusu 3D işlemleri yapmaya özel tasarlanmış bir donanım artık söz konusu işlemlerden sorumlu olduğu için çok daha yüksek performans alınabildi.
Silverlight ile alakası nedir?
Aslına bakarsak Silverlight içerisinde de bolca görsel işlem yapıyoruz. En basit örnek olarak bir video oynatmayı bile ele alabiliriz. Biz videomuzu bir MediaElement ile sahneye koyduğumuzda video dosyasının orijinal yükseklik ve genişliği ile hiç ilgilenmeyiz. Oysa arkaplanda oynatılacak olan video uygun şekillerde MediaElement içerisine yerleştirilir ve aslında gerçek zamanlı olarak videonun içindeki her kare resim tekrar boyutlandırılır. Özellikle Full HD gibi yoğun data içeren yüksek çözünürlüklü videolarda aslında ciddi bir işlem gücü gerekiyor ve şu ana kadar da bu işlemleri Silverlight tarafında bilgisayarımızın işlemcisi üstleniyordu.
Oysa zaten bugün hali hazırda neredeyse her bilgisayarda en kötüsünden bir GPU yok mu? Neredeyse GPU'suz bilgisayar satın alamaz hale geldik. Tabi bu güzel bir gelişme ama bu gelişmeden Silverlight'ın da faydalanması gerek! İşte Silverlight 3.0 ile beraber "GPU Acceleration" denilen GPU (donanım) destekli işlemler ile uygulamanın hızlandırılması artık mümkün.
Video uygulamalarında Hardware Acceleration...
Hemen basit bir şekilde elimizdeki High Definition bir videoyu oynatan Silverlight uygulaması hazırlayalım. Ekrana bir MediaElement koyarak Source özelliğini ayarlamamız yeterli olacaktır.
[XAML]
<UserControl x:Class="SilverlightApplication10.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <MediaElement Source="Wildlife.wmv" />
    </Grid>
</UserControl>
Yukarıdaki XAML kodu ile uygulamamızı çalıştırdığımda herhangi bir sorun yok. Video rahatlıkla oynuyor fakat kendi makinemde yaptığım testte CPU kullanımı %25 civarında geziyor. Acaba sadece bu videonun en azından tekrar boyutlandırma işini işlemciden alıp GPU'ya aktarsak işlemci kullanımı ne kadar düşer?
Silverlight içerisinde varsayılan ayarları ile GPU kullanımı gelmiyor. GPU kullanımını bir uygulamada açmak için söz konusu uygulamanın HTML sayfa içerisine yerleştirildiği OBJECT taglarına ekstra bir parametre geçmeniz gerekiyor.
[HTML]
        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
            <param name="source" value="ClientBin/SilverlightApplication10.xap"/>
            <param name="onerror" value="onSilverlightError" />
            <param name="background" value="white" />
            <param name="minRuntimeVersion" value="3.0.40307.0" />
            <param name="autoUpgrade" value="true" />
            <param name="EnableGPUAcceleration" value="true" />
            <a href="http://go.microsoft.com/fwlink/?LinkID=141205" style="text-decorationnone;">
                 <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-stylenone"/>
            </a>
        </object>
Yukarıdaki HTML kodları arasında da görebileceğiniz üzere artık Silverlight uygulamamızı gösterecek olan OBJECT taglarına ek olarak bir deEnableGPUAcceleration parametresi veriyor ve söz konusu değeri de True olarak set ediyoruz. Böylece artık Silverlight uygulamamız GPU desteğine kavuşacak fakat ek olarak uygulama içerisinde hangi kontrollerin GPU tarafından oluşturulması gerektiğini de belirtmemiz gerekiyor. Bunun için kontrol bazında CacheMode ayarlanıyor. Şu anda sadece CacheMode olarak BitmapCache destekliyor. BitmapCache'in tam olarak ne yaptığına bir sonraki örneğimizde göz atacağız. Şimdilik MediaElement'imize nasıl BitmapCach uygulanır onu görelim.
[XAML]
<UserControl x:Class="SilverlightApplication10.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <MediaElement Source="Bear.wmv" >
            <MediaElement.CacheMode>
                <BitmapCache/>
            </MediaElement.CacheMode>
        </MediaElement>
    </Grid>
</UserControl>
Silverlight içerisinde tüm nesnelerin artık bir CacheMode özelliği var. Bu özelliğe bir BitmapCache vererek donanım desteğini arkanıza alabilirsiniz. Yukarıdaki örneği donanım desteği ile çalıştırdığımda benim makinemde CPU kullanımı %25'ten %20'lere indi. Tabi bu yaptığınız işleme ve GPU'nuzun gücüne göre değişecektir.
Silverlight'ta CPU kullanımı farkları.
Silverlight'ta CPU kullanımı farkları.
Unutmadan birkaç detaya göz atalım. Silverlight'ın donanım desteğini arkasına alabilmesi için hedef makinede DirectX9.0c yüklü olması gerekiyor. Eğer söz konusu yükleme makinede yok ise yine eski tarz yazılım bazlı sisteme geri dönülüyor. Mac ortamı için ekstra bir şart daha var; maalesef Mac ortamında donanım desteği sadece tam ekran modunda çalışabiliyor.
Şu an için GPU'ya aktarılan işlemler Transform, Rectangular Clipping ve Blending işlemleri. İleriki sürümlerde farklı işlemlerin de GPU tarafına aktarılabilmesine dair eklentiler vaatler arasında.
BitmapCache nedir?
Aslında BitmapCache çok dikkatli yaklaşılması gereken bir teknik. Örneğin her noktada BitmapCache kullanmaya başlarsak aslında performans kazanalım derken kaybetmemize de neden olabilir.
Bildiğiniz üzere Silverlight içerisinde sürekli olarak ekran vektörel olarak çiziliyor. Bazı durumlarda özellikle hızlı animasyonlarda anime ettiğiniz nesnenin görsel olarak sürekli yeniden çizilmesini istemeyebilirsiniz. Oysa o görsel vektörel bir tekrar çizme sürecinden geçirmek yerine daha önce çizilmiş vektörel sonucu bitmap olarak kullanmak performans noktasında ciddi katkı sağlayabilir.
BitmapCache'in performansa faydası.
BitmapCache'in performansa faydası.
Yukarıdaki grafik testini yaparken çok sayıda notka içeren bir vektörel çizim kullandım. Söz konusu vektörel çizim XAML kodunu makaleye yapıştırmıyorum çünkü hem anlamsız hem de gereğinden uzun :) Vektörel çizimi bir animasyon ile ekranda sürekli olarak büyütüp küçülttüm. Bu süreçte Normal şartlarda Silverlight her karede vektörel çizim vektör verisinden tekrar çizdi. BitmapCache ile GPU desteğini açtığımda ise ilk başta çizilen vektörel datadan bir Bitmap kopya alıp artık Bitmap koyayı büyütüp küçültmeye başladı. Aradaki %10'a yakın performans farkını yukarıdaki görebilirsiniz.
BitmapCache Mantığı.
BitmapCache Mantığı.
Tabi unutmamak gerek ki vektörel yerine bitmap işlemler yaptırdığınızda sistemin ilk aldığı bitmap içerisinde kalite geçerli olacaktır ve nesne büyüdükçe tekrar çizilmediği için normal animasyonlardaki kalite elde edilemeyecektir. Fakat bazı durumlarda bu kalite farkının kullanıcı tarafından algılanması pek mümkün olmayabiliyor. İşte böyle durumlarda BitmapCache hayat kurtarabilir.
Neresi Cache'den geliyor? Neresi gelmiyor?
BitmapCache ayarlarını yaptıktan sonra uygulamanızı test ederken gerçekten ekranda nerelerin Cache'lenip Cache'lenmediğini görmek isterseniz yine HTML OBJECT tagına geri dönüp aşağıdaki parametreyi ekleyebilirsiniz. Böylece artık Silverlight uygulamanız çalışırken Cache'lenmeye yerleri ayrı renklerde gösterecektir.
[HTML]
        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
            <param name="source" value="ClientBin/SilverlightApplication12.xap"/>
            <param name="onerror" value="onSilverlightError" />
            <param name="background" value="white" />
            <param name="minRuntimeVersion" value="3.0.40307.0" />
            <param name="autoUpgrade" value="true" />
            <param name="EnableGPUAcceleration" value="true" />
            <param name="EnableCacheVisualization" value="true" />
            <a href="http://go.microsoft.com/fwlink/?LinkID=141205" style="text-decorationnone;">
                 <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-stylenone"/>
            </a>
        </object>
Hepinize kolay gelsin.

Hiç yorum yok:

Yorum Gönder