Grafik geliştiricileri ve meraklıları için en keyifli uğraşlardan biri, GPU’ların spesifikasyonlarını karşılaştırmak ve her yeni nesilde artan shader çekirdekleri, RT çekirdekleri, teraflop sayıları ve hesaplama gücüne hayran kalmaktır. Bu güçlerin sunduğu maksimum teorik performansa ulaşmak, grafik programlamada büyük bir odak noktasıdır. Milyonlarca render verisi, üçgenler, pikseller ve ışınlar, GPU’nun son derece paralel hesaplama hattından geçerken, bir üretim tesisinde olduğu gibi akıp gider. Maksimum verimlilik sağlamak için bu fabrikaların sorunsuz çalışması, kesintisiz iş yapması ve hiç bir ekipmanın boş durmaması gerekir.
Bu yazı, Nsight Graphics 2024.3’teki yeni özellikleri ele alacak ve bu sanal üretim hatlarını nasıl daha iyi anlayabilir ve yönetebileceğiniz ile grafik uygulamaları için optimal şekilde paralel yükler oluşturabileceğinizi gösterecektir.
Aktif Warp Başına İplik Histogramı
Warp, programlanabilir shader’lar için temel yürütme birimini oluşturan 32 iplikten oluşan bir gruptur. HLSL veya GLSL’de yazılan ray izleme, hesaplama, vertex, piksel gibi shader’lar makine talimatlarına derlenir ve bu talimatlar nihayetinde warplara bölünerek donanımda çalıştırılır. Warplar paralel olarak çalışır ve yüzlerce warp aynı anda çalıştırılır. Programlanabilir gölgelemenin bir yükün sınırlayıcı faktörü olduğu durumlarda, warpların verimli çalışması, maksimum performansa ulaşmak için hayati öneme sahiptir.
Warplar, bir dizi talimatı yürüten birimlerdir. Her warp, tüm ipliklerine bir talimatı bir seferde yayar; bu durumda, örneğin bir shader kodu iki sayıyı topluyorsa, bu toplama işlemi warptaki 32 iplikte aynı anda çalıştırılır. Sonuç olarak 64 girdiyle 32 eşsiz toplam üretilir.
Warpların verimsiz çalışmasına neden olan durumlardan biri, shader kodundaki dalgalanmalardır. Branching sayesinde (if-durumları vb.) shader kodunda dalgalanma görüldüğünde, derleyici dalgalanmadan tamamen kaçınmayı tercih edebilir. Yani, if-durumuna ait tüm kod bloklarını çalıştırıp kullanılmayan sonuçları göz ardı etmek veya döngüleri döngüleme yoluyla çözebilir. Fakat dinamik bir dalgalanma derlendiğinde ve yürütme zamanında bir warp’taki iplikler arasında uniform olmayan bir koşul ifadeleri varsa, warp hem if gövdesini hem de else gövdesini sırayla çalıştırmak zorunda kalır.
NVIDIA’nın modern GPU’larındaki warp talimat planlaması hakkında daha kapsamlı detaylar için NVIDIA Tesla V100 GPU Mimarisi‘ne başvurabilirsiniz (sayfa 26).
Şekil 1, sekiz iplikten oluşan bir warp’ın dalgalanmasını basit bir şekilde göstermektedir. Büyük harfler, programdaki kod parçalarını temsil etmektedir. Her talimat yürütüldüğünde iplik işçi hatlarındaki boş alanlar nedeniyle verimlilik düşmektedir.
Bu durum, branchless (dalga olmayan) bir şekilde if-durumundaki tüm blokları çalıştırmaktan farklıdır; çünkü gerçek branching, yürütülmeyen ipliklerin yan etkilerini ortadan kaldırır. Daha önemlisi, dinamik bir dalgalanma tersine, kondisyonel ifadelerin dağılımı uygunsa bir kazanç sağlamaktadır. Eğer çok sayıda warp, kondisyonel ifade için homojen bir sonuca sahipse, dalgalanma durumu azalacağı için verimlilik etkilenmeyecektir. Vertex ve piksel shader’larında, warplar vertex ve piksellerin yerleşimlerine göre gruplanır. Ray izleme ve hesaplama shader’larında ise kullanıcı daha açık bir şekilde iş yükünü gruplandırabilir.
Dalgalanmanın performans üzerinde etkili olan diğer faktörler arasında herhangi bir dalga altındaki shader talimatlarının genel yüzdesi ve belirli makine talimatlarının operand türleri bulunur. Gerçek etkisini öğrenmek için warp iplik verimliliğini takip edip, toplam performansa etkisini ölçmek gerekir.
Bu noktada yeni Aktif İplik Başına Warp Histogramı devreye giriyor. Bu kompakt grafik, Nsight Graphics içindeki Shader Profiler görünümleri, Shader Pipeline, Üstten Aşağı, Alt Çizgi, Hot Spots ve Kaynak/Derleme dahil olmak üzere GPU İzleme aracında mevcut. Herhangi bir shader, fonksiyon veya kaynak kodunun bireysel satırı için dalgalanmanın toplam etkisini gösterir.
Şekil 2’de histogramın sağ tarafındaki (32’ye daha yakın) değerler, daha verimli talimat yürütmesini ifade eder. Mevcut değerler, her kod bloğunun yürütüldüğü anda performans sayaçlarının örneklenmesiyle yaklaşık olarak gösterilmektedir. Pop-up bilgi penceresi histogramı daha ayrıntılı bir şekilde gösterebilir. GPU İzleme’yi başlatırken, Zaman Çizelgesi Metri ayarları Üst Düzey Tahlil veya (Ray İzleme Tahlil mevcutsa) olarak ayarlanmalı ve Gerçek Zamanlı Shader Profiler etkinleştirilmelidir.
Bir fonksiyon performans darboğazı yaratıyorsa ve düşük bir Aktif İplik Başına Warp değerine sahipse, warp tutarlılığını iyileştirmek veya branching’i azaltmak için stratejiler düşünmelisiniz. Ray izleme iş yükleri için, dalgalanma ve veri çeşitliliği sorunlarını çözmek için özel olarak tasarlanmış Shader Execution Reordering (SER) kullanabilirsiniz. Diğer algoritmik değişiklikler iplik yürütme tutarlılığını artırabilir; örneğin, farklı bir ışın örnekleme düzeni kullanmak. Herhangi bir shader için, branch’leri warp-bilinçli shader koduna dönüştürerek verimliliği artırmak mümkün olabilir.
Histogramın yayılması, kod bloğunun davranışının ne kadar tutarsız olduğunu ortaya koyar ve %100’e yakın Aktif İplik Başına Warp değerinin görülmesi, dalgalanmanın başlangıçta kısıtlayıcı olduğunu düşündüğünüzde yapılacak başka bir doğrulamadır.
Şekil 3, yol izleme gibi gelişmiş aydınlatma tekniklerinin shader dalgalanmasına nasıl neden olduğunu göstermektedir. SER, ışınların aynı hit shader’ını kullandığında daha iyi kullanır ve bu durum, warp düzeyindeki SIMT’den daha iyi yararlanır. SER çalıştığında, Aktif İplik Başına Warp değerinin iyileştirilmiş olduğunu görmelisiniz.
Warp Gecikmeleri ve Yeni Histogram Özellikleri
Daha yüksek bir düzeyde, genel gölgeleme süresini iyileştirmek, warp gecikmelerini anlama ve azaltma ile başlar. Warplar, uzun gecikme gerektiren işlemlerle özellikle bellek erişimleri ve doku alımları için durakladıklarında verimliliği düşürmektedir. Bir warp durakladığında, bir sonraki talimat için başka bir warp’a programlanabilir. Ancak bu, yalnızca belirli bir şekilde paralellik sağlar. Eğer çok fazla warp duraklarsa, SM kullanılmaz veya hatta boş kalır. Bu duraklama süresi, bellek araması sırasında hangi önbellek seviyesinin vurulduğuna bağlı olarak farklılık gösterebilir.
GPU İzleme, bu duraklamaları analiz etmek için her zaman araçlar sunmuştur, ancak yeni bir ek özellik olarak, daha önce tek bir Ortalama Warp Gecikme döngü sayısı olarak sunulan Warp Gecikmesi Histogramı eklenmiştir. Warp gecikmelerinin dağılımını görmek, shader zamanlamalarındaki değişkenlik hakkında daha fazla bilgi sunar.
D3D12 İş Grafiklerinde İyileştirmeler
CPU ve GPU arasındaki iletişim, grafik boru hatlarındaki bir başka yaygın darboğazdır. Toplu verilerin GPU’da tutulması durumunda dahi, CPU’dan görüntüleme talimatları vermek GPU’nun durakladığı boşluklar yaratabilir. İş Grafikleri, GPU’nun görevleri planlamak için CPU’ya bağımlılığı azaltmayı amaçlayan yeni bir D3D12 özelliğidir. GPU destekli planlama bir süredir mevcuttu, ancak İş Grafikleri daha gelişmiş yetenekler sunmaktadır. İş Grafiklerinin genel bir anlatımını ve detaylarını Direct3D 12 ile GPU Destekli Görselleştirme başlıklı makalede görebilirsiniz.
İlk olarak, Shader Profiler’da İş Grafik düğümlerinin bütün olarak profilini çıkarmak için destek tanıtıldı. 2024.3 ile birlikte Shader Profiler, İş Grafiklerinin performans özelliklerini keşfetme ve daha iyi anlamayı sağlayacak ‘kod kaynakları’ ile tam işlevsellik sağlar. Unutmayın ki, kaynak korelasyonu en yeni R565 sürücü gerektirir.
Vulkan Güncellemeleri
Yeni yayınlanan Vulkan 1.4 standardı, ondan fazla önceki isteğe bağlı uzantıyı gereksinim setine dahil etmekte ve minimum donanım limitlerini artırmaktadır. Vulkan 1.4 hakkında daha fazla ayrıntı için Khronos’un açıklamasını okuyabilirsiniz. Nsight Graphics 2024.3, Frame Debugger içinde Vulkan 1.4 desteğiyle birlikte sunulmaktadır. 1.4’ü destekleyen beta sürücüleri için Vulkan Sürücü Desteği sayfasını ziyaret edin.
Vulkan 1.4’ü doğrudan kullanmasanız bile, artık tüm yeni terfi edilen uzantılar Nsight Graphics’te desteklenmektedir. Ayrıca, VK_NV_inherited_viewport_scissor ve VK_NV_device_generated_commands_compute gibi birçok uzantı için destek eklenmiştir. Tam liste için NVIDIA Nsight Graphics Kullanım Kılavuzu‘na bakabilirsiniz.
Bu sürüm, Windows ve Linux masaüstü platformlarında Vulkan SC kullanan uygulamalar için Frame Debugging ve GPU İzleme desteği de eklemektedir. Vulkan SC hakkında daha fazla bilgi ve sürücü desteği için Vulkan Sürücü Desteği’ni ziyaret edin.
Sonuç
Paralelleşme için optimizasyon yapmadan önce GPU hesaplama modeline dair temel bir anlayışa sahip olmalısınız. Ancak teorinin pratikte nasıl dönüşeceğini tahmin etmek zor olabilir; çünkü veri kalıpları, derleyici ve donanım optimizasyonları gibi pek çok faktör etkilidir. Bu durumda, hipotez testleri ve ölçüm kayıtları ile stratejik bir yaklaşım izlemek önemlidir. Ölçümlerin ne anlama geldiğini anlayarak, değişiklik yaptıkça bunların nasıl değiştiğini takip etmelisiniz. GPU üzerindeki her donanım biriminin aynı anda %100 kullanılmasını sağlamak pratik olmasa da, kademeli iyileştirmeler uygulamanızın performans gereksinimlerini karşılamaya yardımcı olabilir.
Nsight Graphics 2024.3 artık kullanıma sunuldu. Bu yeni özellikler ile ilgili deneyimlerinizi, Nsight Graphics penceresinin sağ üst köşesindeki Geri Bildirim butonuna tıklayarak bizimle paylaşabilirsiniz.
Nsight Geliştirici Araçları hakkında daha fazla bilgi edinin ve Nsight Araçları için öğreticilere göz atın. Sorularınızı sorun, geri dönüş yapın ve grafik geliştirici topluluğuyla Nsight Graphics Geliştirici forumu‘nda etkileşimde bulunun.
Teşekkürler
Bu yazıya katkıda bulunan Avinash Baliga, Jeff Kiel, Axel Mamode, Aurelio Reis ve Louis Bavoil’a teşekkür ederim.