Ev / Ofis / GPU grafik kartında madencilik - eksiksiz bir kılavuz. GPU'nun etkili kullanımı Görev yöneticisinde neden GPU yok?

GPU grafik kartında madencilik - eksiksiz bir kılavuz. GPU'nun etkili kullanımı Görev yöneticisinde neden GPU yok?

Geliştiricinin, uygulamanın yavaşlamaması veya gereksiz işler yapmaması için cihazın grafik işlem birimini (GPU) etkili bir şekilde kullanmayı öğrenmesi gerekir.

GPU oluşturma ayarlarını yapılandırma

Uygulamanız yavaşsa bu, ekranın yenileme çerçevelerinin bir kısmının veya tamamının yenilenmesinin 16 milisaniyeden uzun sürdüğü anlamına gelir. Çerçeve güncellemelerini ekranda görsel olarak görmek için cihazda özel bir seçeneği etkinleştirebilirsiniz (Profil GPU Oluşturma).

Çerçeveleri oluşturmanın ne kadar sürdüğünü hızlı bir şekilde görebileceksiniz. 16 milisaniye içerisinde tutmanız gerektiğini hatırlatayım.

Bu seçenek Android 4.1 ile başlayan cihazlarda mevcuttur. Cihazda geliştirici modunun etkinleştirilmesi gerekir. Sürüm 4.2 ve üzeri olan cihazlarda mod varsayılan olarak gizlidir. Etkinleştirmek için şuraya gidin: Ayarlar | Telefon hakkında ve çizgiye yedi kez tıklayın Yapı numarası.

Etkinleştirmeden sonra şuraya gidin: Geliştirici Seçenekleri ve noktayı bul GPU oluşturma ayarlarını yapılandırma(Profil GPU oluşturma) etkinleştirilmesi gerekir. Açılan pencerede seçeneği seçin Sütunlar halinde ekranda(Ekranda çubuklar halinde). Bu durumda grafik, çalışan uygulamanın üstünde görüntülenecektir.

Yalnızca uygulamanızı değil, başkalarını da test edebilirsiniz. Herhangi bir uygulamayı başlatın ve onunla çalışmaya başlayın. Çalışırken ekranın alt kısmında güncellenmiş bir grafik göreceksiniz. Yatay eksen geçen süreyi temsil eder. Dikey eksen her karenin süresini milisaniye cinsinden gösterir. Uygulamayla etkileşimde bulunulduğunda ekranda soldan sağa doğru görünen ve zaman içindeki çerçeve performansını gösteren dikey çubuklar çizilir. Bu tür sütunların her biri, ekranın çizilmesi için bir çerçeveyi temsil eder. Sütun yüksekliği ne kadar yüksek olursa çizim o kadar fazla zaman alır. İnce yeşil çizgi bir kılavuzdur ve kare başına 16 milisaniyeye karşılık gelir. Bu nedenle uygulamanızı incelerken grafiğin bu çizginin dışına çıkmamasını sağlamaya çalışmalısınız.

Grafiğin daha büyük bir versiyonuna bakalım.

Yeşil çizgi 16 milisaniyeden sorumludur. Saniyede 60 kare içinde kalmak için her grafik çubuğunun bu çizginin altına çizilmesi gerekir. Bir noktada sütun çok büyük olacak ve yeşil çizgiden çok daha yüksek olacaktır. Bu, programın yavaşladığı anlamına gelir. Her sütunda camgöbeği, mor (Lolipop ve üzeri), kırmızı ve turuncu bulunur.

Mavi renk, oluşturmak ve güncellemek için kullanılan zamandan sorumludur Görüş.

Mor kısım, iş parçacığının oluşturma kaynaklarını aktarmak için harcanan zamanı temsil eder.

Kırmızı renk çizim süresini temsil eder.

Turuncu renk, CPU'nun GPU'nun işini tamamlamasını beklemesinin ne kadar sürdüğünü gösterir. Büyük değerlerde sorunların kaynağı budur.

GPU üzerindeki yükü azaltmak için özel teknikler vardır.

GPU aşırı yüklenme göstergesinde hata ayıklama

Başka bir ayar, ekranın aynı bölümünün ne sıklıkla yeniden çizildiğini (yani fazladan iş yapıldığını) bilmenizi sağlar. Tekrar gidelim Geliştirici Seçenekleri ve noktayı bul GPU aşırı yüklenme göstergesinde hata ayıklama(GPU Aşırı Çiziminde Hata Ayıklama) etkinleştirilmelidir. Açılan pencerede seçeneği seçin Yer paylaşımı bölgelerini göster(Fazla çizim alanlarını göster). Korkma! Ekrandaki bazı öğelerin rengi değişecek.

Herhangi bir uygulamaya geri dönün ve çalışmasını izleyin. Renk, uygulamanızdaki sorunlu alanları gösterecektir.

Uygulamadaki renk değişmediyse her şey yolunda demektir. Bir rengin diğerinin üzerine katmanlanması yoktur.

Mavi renk, alt katmanın üstüne bir katmanın çizildiğini gösterir. İyi.

Yeşil renk - iki kez yeniden çizildi. Optimizasyon hakkında düşünmeniz gerekir.

Pembe renk - üç kez yeniden çizildi. Her şey çok kötü.

Kırmızı renk - birçok kez yeniden çizildi. Bir şeyler ters gitti.

Sorunlu alanları bulmak için uygulamanızı kendiniz kontrol edebilirsiniz. Bir aktivite oluşturun ve üzerine bir bileşen yerleştirin Metin Görünümü. Kök öğeye ve metin etiketine özellikte biraz arka plan verin android:arka plan. Şunu elde edeceksiniz: İlk olarak, aktivitenin en alttaki katmanını tek renkle boyadınız. Daha sonra üzerine yeni bir katman çizilir. Metin Görünümü. Bu arada, aslında Metin Görünümü metin de çizilir.

Bazı noktalarda renklerin üst üste gelmesinden kaçınılamaz. Ancak listenin arka planını da aynı şekilde ayarladığınızı düşünün. Liste Görünümü, tüm faaliyet alanını kaplar. Kullanıcı etkinliğin alt katmanını hiçbir zaman görmese de sistem çift görev yapacaktır. Ayrıca, listenin her öğesi için kendi arka planıyla kendi işaretlemenizi oluşturursanız, genellikle aşırıya kaçarsınız.

Küçük bir tavsiye. Yöntemden sonra yerleştirin setContentView() ekranın tema rengiyle boyanmasını kaldıracak bir yöntem çağırmak. Bu, fazladan bir renk katmanının kaldırılmasına yardımcı olacaktır:

GetWindow().setBackgroundDrawable(null);

GPU Hesaplamayı C++ AMP ile Kullanma

Şu ana kadar paralel programlama tekniklerini tartışırken yalnızca işlemci çekirdeklerini ele aldık. Programları birden fazla işlemcide paralelleştirme, paylaşılan kaynaklara erişimi senkronize etme ve kilit kullanmadan yüksek hızlı senkronizasyon temellerini kullanma konusunda bazı beceriler edindik.

Ancak programları paralelleştirmenin başka bir yolu daha var: grafik işlem birimleri (GPU'lar), yüksek performanslı işlemcilerden bile daha fazla çekirdeğe sahip. GPU çekirdekleri, paralel veri işleme algoritmalarını uygulamak için mükemmeldir ve çok sayıda olmaları, üzerlerinde program çalıştırmanın verdiği rahatsızlığı fazlasıyla karşılar. Bu makalede, adı verilen bir dizi C++ dil uzantısını kullanarak GPU'da programları çalıştırmanın yollarından biriyle tanışacağız. C++AMP.

C++ AMP uzantıları C++ dilini temel alır, bu nedenle bu makale C++'daki örnekleri gösterecektir. Bununla birlikte, etkileşim mekanizmasının orta derecede kullanılmasıyla. NET ile .NET programlarınızda C++ AMP algoritmalarını kullanabilirsiniz. Ancak bunun hakkında makalenin sonunda konuşacağız.

C++ AMP'ye giriş

Temel olarak GPU, diğerleriyle aynı işlemcidir ancak özel bir talimat dizisine, çok sayıda çekirdeğe ve kendi bellek erişim protokolüne sahiptir. Ancak modern GPU'lar ile geleneksel işlemciler arasında büyük farklar vardır ve bunları anlamak, bilgi işlem gücünü verimli bir şekilde kullanan programlar oluşturmanın anahtarıdır. GPU.

    Modern GPU'ların çok küçük bir talimat seti vardır. Bu, bazı sınırlamalar anlamına gelir: işlevleri çağırma yeteneğinin olmaması, sınırlı sayıda desteklenen veri türü, kitaplık işlevlerinin eksikliği ve diğerleri. Koşullu dallandırmalar gibi bazı işlemler, geleneksel işlemcilerde gerçekleştirilen benzer işlemlerden önemli ölçüde daha pahalıya mal olabilir. Açıkçası, bu tür koşullar altında büyük miktarda kodu CPU'dan GPU'ya taşımak ciddi çaba gerektirir.

    Ortalama GPU'daki çekirdek sayısı, ortalama geleneksel işlemcidekinden önemli ölçüde daha yüksektir. Ancak bazı görevler çok küçüktür veya GPU'dan yararlanabilecek kadar büyük parçalara bölünemez.

    Aynı görevi gerçekleştiren GPU çekirdekleri arasındaki senkronizasyon desteği çok zayıftır ve farklı görevleri gerçekleştiren GPU çekirdekleri arasında ise tamamen yoktur. Bu durum grafik işlemcinin geleneksel bir işlemciyle senkronize edilmesini gerektirir.

Hemen şu soru ortaya çıkıyor: GPU'da hangi görevler çözülmeye uygundur? Her algoritmanın GPU'da çalıştırılmaya uygun olmadığını unutmayın. Örneğin, GPU'ların G/Ç cihazlarına erişimi yoktur, dolayısıyla RSS beslemelerini İnternet'ten alan bir programın performansını GPU kullanarak artıramazsınız. Ancak birçok hesaplama algoritması GPU'ya aktarılabilir ve büyük ölçüde paralelleştirilebilir. Aşağıda bu tür algoritmaların birkaç örneği verilmiştir (bu liste hiçbir şekilde tam değildir):

    görüntülerin keskinliğinin arttırılması ve azaltılması ve diğer dönüşümler;

    hızlı Fourier dönüşümü;

    matris aktarımı ve çarpımı;

    sayı sıralama;

    doğrudan hash inversiyonu.

Ek örnekler için mükemmel bir kaynak, C++ AMP'de uygulanan çeşitli algoritmalar için kod parçacıkları ve açıklamalar sağlayan Microsoft Native Concurrency blogudur.

C++ AMP, Visual Studio 2012'de yer alan ve C++ geliştiricilerine GPU üzerinde hesaplamalar gerçekleştirmenin basit bir yolunu sunan ve yalnızca DirectX 11 sürücüsü gerektiren bir çerçevedir. Microsoft, C++ AMP'yi herhangi bir derleyici satıcısı tarafından uygulanabilecek açık bir spesifikasyon olarak yayımladı.

C++ AMP çerçevesi, kodu çalıştırmanıza olanak tanır grafik hızlandırıcılar bunlar bilgi işlem cihazlarıdır. DirectX 11 sürücüsünü kullanan C++ AMP çerçevesi, tüm hızlandırıcıları dinamik olarak algılar. C++ AMP ayrıca bir yazılım hızlandırıcı emülatörü ve GPU'su olmayan veya GPU'su olan ancak DirectX 11 sürücüsü olmayan sistemlerde geri dönüş görevi gören ve birden fazla çekirdek ve SIMD talimatları kullanan geleneksel işlemci tabanlı bir emülatör olan WARP'yi içerir.

Şimdi GPU'da yürütülmek üzere kolaylıkla paralelleştirilebilecek bir algoritmayı keşfetmeye başlayalım. Aşağıdaki uygulama eşit uzunlukta iki vektör alır ve noktasal sonucu hesaplar. Bundan daha basit bir şey hayal etmek zor:

Void VectorAddExpPointwise(float* birinci, float* ikinci, float* sonuç, int uzunluk) ( for (int i = 0; i< length; ++i) { result[i] = first[i] + exp(second[i]); } }

Bu algoritmayı normal bir işlemcide paralelleştirmek için yineleme aralığını birkaç alt aralığa bölmeniz ve bunların her biri için bir yürütme iş parçacığı çalıştırmanız gerekir. İlk arama örneğimizi paralelleştirmenin tam olarak bu yöntemine önceki makalelerimizde oldukça fazla zaman ayırmıştık. asal sayılar- iş parçacıklarını manuel olarak oluşturarak, işleri bir iş parçacığı havuzuna aktararak ve otomatik olarak paralelleştirmek için Parallel.For ve PLINQ kullanarak bunu nasıl yapabileceğimizi gördük. Benzer algoritmaları geleneksel bir işlemcide paralelleştirirken, sorunu çok küçük görevlere bölmemeye özellikle dikkat ettiğimizi de unutmayın.

GPU için bu uyarılara gerek yoktur. GPU'lar, iş parçacıklarını çok hızlı bir şekilde yürüten birden fazla çekirdeğe sahiptir ve bağlam değiştirmenin maliyeti, geleneksel işlemcilere göre önemli ölçüde daha düşüktür. Aşağıda işlevi kullanmaya çalışan bir pasaj var paralel_for_each C++ AMP çerçevesinden:

#katmak #katmak ad alanı eşzamanlılığını kullanma; void VectorAddExpPointwise(float* birinci, float* ikinci, float* sonuç, int uzunluk) ( array_view avFirst(uzunluk, ilk); dizi_görünümü avSecond(uzunluk, saniye);<1>i) kısıtlama(amp) ( avResult[i] = avFirst[i] + fast_math::exp(avSecond[i]); ));

avResult.synchronize(); )

Şimdi kodun her bir parçasını ayrı ayrı inceleyelim. Ana döngünün genel biçiminin korunduğunu, ancak başlangıçta kullanılan for döngüsünün yerini paralel_for_each işlevine yapılan bir çağrı aldığını hemen belirtelim. Aslında, bir döngüyü bir işleve veya yöntem çağrısına dönüştürme ilkesi bizim için yeni değildir; böyle bir teknik daha önce TPL kitaplığındaki Parallel.For() ve Parallel.ForEach() yöntemleri kullanılarak gösterilmiştir. Daha sonra, giriş verileri (birinci, ikinci ve sonuç parametreleri) örneklerle sarılır dizi_görünümü

. array_view sınıfı GPU'ya (hızlandırıcı) iletilen verileri sarmak için kullanılır. Şablon parametresi veri türünü ve boyutunu belirtir. Orijinal olarak geleneksel bir CPU'da işlenen verilere erişen bir GPU üzerindeki talimatları yürütmek için, birisinin veya bir şeyin verileri GPU'ya kopyalamakla ilgilenmesi gerekir çünkü çoğu modern grafik kartı, kendi belleğine sahip ayrı cihazlardır. array_view örnekleri bu sorunu çözer; talep üzerine ve yalnızca gerçekten ihtiyaç duyulduğunda veri kopyalama sağlarlar. GPU görevi tamamladığında veriler geri kopyalanır. Array_view'i const argümanıyla başlatarak, birinci ve ikincinin GPU belleğine kopyalanmasını ancak geri kopyalanmamasını sağlıyoruz. Aynı şekilde arama throw_data()

, normal bir işlemcinin belleğinden hızlandırıcı belleğine kopyalama sonucunu hariç tutuyoruz, ancak bu veriler ters yönde kopyalanacaktır.

paralel_for_each işlevi, işlenecek verinin biçimini belirten bir kapsam nesnesini ve kapsam nesnesindeki her öğeye uygulanacak bir işlevi alır. Yukarıdaki örnekte, ISO C++2011 (C++11) standardında desteklenen bir lambda işlevi kullandık. Kısıtlama (amp) anahtar sözcüğü, derleyiciye, işlev gövdesinin GPU'da yürütülüp yürütülemeyeceğini kontrol etme talimatını verir ve GPU talimatlarında derlenemeyen çoğu C++ sözdizimini devre dışı bırakır.<1>Lambda fonksiyon parametresi, indeks

Son olarak yöntem çağrısı senkronize() VectorAddExpPointwise yönteminin sonunda GPU tarafından üretilen array_view avResult hesaplama sonuçlarının tekrar result dizisine kopyalanmasını sağlar.

Bu, C++ AMP dünyasına ilk tanıtımımızı tamamlıyor ve artık daha ayrıntılı araştırmaların yanı sıra GPU'da paralel hesaplama kullanmanın faydalarını gösteren daha ilginç örneklere hazırız. Vektör ekleme iyi bir algoritma değildir ve veri kopyalamanın büyük yükü nedeniyle GPU kullanımını göstermek için en iyi aday değildir. Bir sonraki alt bölüm iki ilginç örnek daha gösterecek.

Matris çarpımı

Bakacağımız ilk "gerçek" örnek matris çarpımıdır. Uygulama için, yürütme süresi kübik ~O(n 2,807)'ye yakın olan Strassen algoritmasını değil, basit bir kübik matris çarpım algoritmasını alacağız. Bir m x w matrisi A ve bir w x n matrisi B olmak üzere iki matris verildiğinde, aşağıdaki program bunları çarpacak ve sonucu, yani bir m x n matrisi C'yi döndürecektir:

Void MatrixMultiply(int* A, int m, int w, int* B, int n, int* C) ( for (int i = 0; i< m; ++i) { for (int j = 0; j < n; ++j) { int sum = 0; for (int k = 0; k < w; ++k) { sum += A * B; } C = sum; } } }

Bu uygulamayı paralelleştirmenin birkaç yolu vardır ve bu kodu normal bir işlemcide çalışacak şekilde paralelleştirmek istiyorsanız, doğru seçim dış döngüyü paralelleştirmek olacaktır. Ancak GPU'nun oldukça fazla sayıda çekirdeği var ve yalnızca dış döngüyü paralelleştirerek tüm çekirdeklere iş yüklemeye yetecek sayıda iş oluşturamayacağız. Bu nedenle, iç döngüye dokunulmadan iki dış döngüyü paralelleştirmek mantıklıdır:

Void MatrixMultiply (int* A, int m, int w, int* B, int n, int* C) ( array_view avA(m, w, A); dizi_görünümü avB(w, n, B);<2>dizi_görünümü< w; ++k) { sum + = avA(idx*w, k) * avB(k*w, idx); } avC = sum; }); }

Bu uygulama, artık iki boyutlu olan ve operatör kullanılarak iç döngüde erişilebilen indeks haricinde, matris çarpımının sıralı uygulamasına ve yukarıda verilen vektör toplama örneğine çok benzemektedir. Bu sürüm normal bir işlemcide çalışan sıralı alternatiften ne kadar daha hızlı? 1024 x 1024 boyutunda iki matrisin (tamsayılar) çarpılmasıyla, normal bir CPU'daki sıralı sürüm ortalama 7350 milisaniye sürerken, GPU sürümü - sıkı tutun - 50 milisaniye sürer, yani 147 kat daha hızlı!

Parçacık hareketi simülasyonu

Yukarıda sunulan GPU'daki sorunları çözme örnekleri, iç döngünün çok basit bir uygulamasına sahiptir. Bunun her zaman böyle olmayacağı açıktır. Yukarıda bağlantısı verilen Native Concurrency blogu, parçacıklar arasındaki yerçekimsel etkileşimlerin modellenmesine ilişkin bir örnek göstermektedir. Simülasyon sonsuz sayıda adım içerir; her adımda her parçacık için ivme vektörünün elemanlarının yeni değerleri hesaplanır ve ardından yeni koordinatları belirlenir. Burada parçacık vektörü paralelleştirilmiştir - yeterince büyük sayıda parçacıkla (birkaç bin ve üzeri), tüm GPU çekirdeklerini işle yüklemek için yeterince büyük sayıda görev oluşturabilirsiniz.

Algoritmanın temeli, aşağıda gösterildiği gibi GPU'ya kolayca aktarılabilen iki parçacık arasındaki etkileşimlerin sonucunun belirlenmesinin uygulanmasıdır:

// burada float4 dört elemanlı vektörlerdir // işlemlerde yer alan parçacıkları temsil eder void bodybody_interaction (float4& ivme, const float4 p1, const float4 p2) kısıtlama(amp) ( float4 dist = p2 – p1; // burada kullanılmadı float absDist = dist.x*dist.x + dist.y*dist.y + dist.z*dist.z; float invDist = 1.0f / sqrt(absDist); float invDistCube = invDist*invDist*invDist; PARTICLE_MASS*invDistCube )

Her modelleme adımında başlangıç ​​verileri parçacıkların koordinatlarını ve hızlarını içeren bir dizidir ve hesaplamalar sonucunda parçacıkların koordinatlarını ve hızlarını içeren yeni bir dizi oluşturulur:

Yapı parçacığı (float4 konumu, hız; // kurucunun, kopya kurucunun ve // ​​operatörün uygulamaları = yerden tasarruf etmek için kısıtlama(amp) atlandı); void simülasyon_step(dizi & önceki, dizi & sonraki, int gövdeler) ( kapsam<1>ext(gövdeler);<1>idx) kısıtlama(amp) ( parçacık p = önceki; float4 ivme(0, 0, 0, 0); for (int gövde = 0; gövde< bodies; ++body) { bodybody_interaction (acceleration, p.position, previous.position); } p.velocity + = acceleration*DELTA_TIME; p.position + = p.velocity*DELTA_TIME; next = p; }); }

Uygun bir grafik arayüzün yardımıyla modelleme çok ilginç olabilir. C++ AMP ekibi tarafından sağlanan tam örnek Native Concurrency blogunda bulunabilir. Intel Core i7 işlemcili ve Geforce GT 740M grafik kartına sahip sistemimde, 10.000 parçacığın simülasyonu, normal işlemcide çalışan sıralı sürüm kullanılarak ~2,5 fps (saniyedeki adım sayısı) hızında ve optimize edilmiş sürüm çalıştırıldığında 160 fps hızında çalışır. GPU'da - performansta büyük bir artış.

Bu bölümü tamamlamadan önce, C++ AMP çerçevesinin GPU'da çalışan kodun performansını daha da artırabilecek önemli bir özelliği daha var. GPU desteği programlanabilir veri önbelleği(sıklıkla denir paylaşılan hafıza). Bu önbellekte saklanan değerler, tek bir döşemedeki tüm yürütme iş parçacıkları tarafından paylaşılır. Bellek döşemesi sayesinde, C++ AMP çerçevesini temel alan programlar, grafik kartı belleğindeki verileri mozaiğin paylaşılan belleğine okuyabilir ve ardından verileri grafik kartı belleğinden yeniden getirmeden birden fazla yürütme iş parçacığından bu verilere erişebilir. Mozaik paylaşımlı belleğe erişim, grafik kartı belleğine göre yaklaşık 10 kat daha hızlıdır. Başka bir deyişle okumaya devam etmek için nedenleriniz var.

Paralel döngünün döşenmiş bir versiyonunu sağlamak için paralel_for_each yöntemi iletilir alan adı Tiled_extentçok boyutlu kapsam nesnesini çok boyutlu döşemelere bölen Tiled_index lambda parametresi ve döşeme içindeki iş parçacığının genel ve yerel kimliğini belirtir. Örneğin, 16x16'lık bir matris 2x2 parçaya bölünebilir (aşağıdaki resimde gösterildiği gibi) ve ardından paralel_for_each işlevine aktarılabilir:

Kapsam<2>matris(16,16); kiremitli_extent<2,2>kiremitliMatrix = matris.tire<2,2>(); paralel_for_each(tiledMatrix, [=](tiled_index<2,2>idx) kısıtlama(amp) ( // ... ));

Aynı mozaiğe ait dört yürütme iş parçacığından her biri, blokta depolanan verileri paylaşabilir.

Standart dizin yerine GPU çekirdeğinde matrislerle işlemler gerçekleştirirken<2>yukarıdaki örneklerde olduğu gibi kullanabilirsiniz idx.global. Yerel döşemeli belleğin ve yerel dizinlerin doğru kullanımı önemli performans kazanımları sağlayabilir. Tek bir döşemedeki tüm yürütme iş parçacıkları tarafından paylaşılan döşemeli belleği bildirmek için, yerel değişkenlertile_static belirticiyle bildirilebilir.

Uygulamada, paylaşılan hafızayı bildirme ve bireysel bloklarını farklı yürütme iş parçacıklarında başlatma tekniği sıklıkla kullanılır:

Parallel_for_each(tiledMatrix, [=](tiled_index<2,2>idx) kısıtlama(amp) ( // 32 bayt, bloktaki tüm iş parçacıkları tarafından paylaşılır kile_statik int local; // bu yürütme iş parçacığı için öğeye bir değer atayın local = 42; ));

Açıkçası, paylaşılan hafızayı kullanmanın herhangi bir faydası ancak bu hafızaya erişim senkronize edildiğinde elde edilebilir; yani, iş parçacıklarından biri tarafından başlatılana kadar iş parçacıklarının belleğe erişmemesi gerekir. Mozaikteki iş parçacıklarının senkronizasyonu nesneler kullanılarak gerçekleştirilir kiremit_barrier(TPL kütüphanesindeki Barrier sınıfını anımsatır) - yalnızcatile_barrier.Wait() yöntemini çağırdıktan sonra yürütmeye devam edebilecekler; bu, yalnızca tüm iş parçacıkları Tile_barrier.Wait'i çağırdığında kontrolü geri döndürecektir. Örneğin:

Parallel_for_each(tiledMatrix, (tiled_index)<2,2>idx) kısıtlama(amp) ( // 32 bayt, bloktaki tüm iş parçacıkları tarafından paylaşılır kiremit_statik int local; // bu yürütme iş parçacığı için öğeye bir değer atayın local = 42; // idx.barrier, karo_barrier'ın bir örneğidir idx.barrier.wait(); // Artık bu iş parçacığı "yerel" diziye erişebilir, // diğer yürütme iş parçacıklarının dizinlerini kullanarak ));

Şimdi öğrendiklerinizi somut bir örneğe dönüştürmenin zamanı geldi. Döşeme belleği organizasyonu kullanılmadan gerçekleştirilen matris çarpımı uygulamasına dönelim ve açıklanan optimizasyonu buna ekleyelim. Matris boyutunun 256'nın katı olduğunu varsayalım - bu, 16 x 16 blokla çalışmamıza olanak tanıyacaktır. Matrislerin doğası blok blok çarpmaya izin verir ve bu özellikten yararlanabiliriz (aslında bölme). matrislerin bloklara dönüştürülmesi, matris çarpım algoritmasının tipik bir optimizasyonudur ve daha verimli CPU önbellek kullanımı sağlar).

Bu tekniğin özü aşağıdakilere inmektedir. C i,j'yi (sonuç matrisinde i satırı ve j sütunundaki öğe) bulmak için, A i,* (ilk matrisin i'inci satırı) ile B *,j (j) arasındaki nokta çarpımı hesaplamanız gerekir. -ikinci matristeki -th sütunu). Ancak bu, satır ve sütunun kısmi nokta çarpımlarının hesaplanmasına ve ardından sonuçların toplanmasına eşdeğerdir. Bu gerçeği matris çarpım algoritmasını döşeme versiyonuna dönüştürmek için kullanabiliriz:

Void MatrixMultiply(int* A, int m, int w, int* B, int n, int* C) ( array_view avA(m, w, A); dizi_görünümü avC(m, n, C);<16,16>avC.discard_data();<16,16>paralel_for_each(avC.extent.tile

(), [=](tiled_index

idx) kısıtlama(amp) ( int toplam = 0; int localRow = idx.local, localCol = idx.local; for (int k = 0; k

Açıklanan optimizasyonun özü, mozaikteki her iş parçacığının (16 x 16 blok için 256 iş parçacığı oluşturulmuştur), orijinal A ve B matrislerinin parçalarının 16 x 16 yerel kopyasında kendi öğesini başlatmasıdır. Mozaikteki her iş parçacığı, bu blokların yalnızca bir satırı ve bir sütunu vardır, ancak tüm iş parçacıkları birlikte her satıra ve her sütuna 16 kez erişecektir. Bu yaklaşım ana belleğe erişim sayısını önemli ölçüde azaltır.

C++ AMP çerçevesine ilişkin tartışmamızı bitirmeden önce, geliştiricilerin kullanabileceği araçlardan (Visual Studio'da) bahsetmek istiyoruz. Visual Studio 2012, kesme noktalarını ayarlamanıza, çağrı yığınını incelemenize ve yerel değişken değerlerini okuyup değiştirmenize olanak tanıyan bir grafik işleme birimi (GPU) hata ayıklayıcı sunar (bazı hızlandırıcılar doğrudan GPU hata ayıklamasını destekler; diğerleri için Visual Studio bir yazılım simülatörü kullanır) ve bir uygulamanın GPU kullanarak işlemleri paralelleştirmeden elde ettiği faydaları değerlendirmenize olanak tanıyan bir profil oluşturucu. Visual Studio'daki hata ayıklama özellikleri hakkında daha fazla bilgi için Walkthrough makalesine bakın. MSDN'de C++ AMP Uygulamasında Hata Ayıklama".

.NET'te GPU Hesaplama Alternatifleri

Bu makalede şu ana kadar yalnızca C++ örnekleri gösterilmiş olsa da, yönetilen uygulamalarda GPU'nun gücünden yararlanmanın birkaç yolu vardır. Bunun bir yolu, GPU çekirdekleriyle yapılan işi düşük seviyeli C++ bileşenlerine aktarmanıza olanak tanıyan birlikte çalışma araçlarını kullanmaktır. Bu çözüm, C++ AMP çerçevesini kullanmak isteyenler veya yönetilen uygulamalarda önceden oluşturulmuş C++ AMP bileşenlerini kullanma becerisine sahip olanlar için mükemmeldir.

Başka bir yol da yönetilen koddan doğrudan GPU ile çalışan bir kitaplık kullanmaktır. Şu anda bu tür birkaç kütüphane var. Örneğin, GPU.NET ve CUDAfy.NET (her ikisi de ticari teklifler). Aşağıda iki vektörün nokta çarpımının uygulanmasını gösteren GPU.NET GitHub deposundan bir örnek verilmiştir:

Public static void MultiplyAddGpu(double a, double b, double c) ( int ThreadId = BlockDimension.X * BlockIndex.X + ThreadIndex.X; int TotalThreads = BlockDimension.X * GridDimension.X; for (int ElementIdx = ThreadId; ElementIdx)

Bir dil uzantısını (C++ AMP'ye dayalı olarak) öğrenmenin, kütüphane düzeyinde etkileşimleri düzenlemeye çalışmaktan veya IL dilinde önemli değişiklikler yapmaktan çok daha kolay ve daha verimli olduğu kanaatindeyim.

Dolayısıyla, .NET'te paralel programlama ve GPU kullanma olanaklarını inceledikten sonra, paralel hesaplamayı düzenlemenin üretkenliği artırmanın önemli bir yolu olduğundan hiç kimsenin şüphesi kalmadı. Dünyanın dört bir yanındaki birçok sunucu ve iş istasyonunda, CPU'ların ve GPU'ların paha biçilemez işlem gücü, uygulamalar onu kullanmadığı için kullanılmaz hale gelir.

Görev Paralel Kütüphanesi bize mevcut tüm CPU çekirdeklerini dahil etmek için eşsiz bir fırsat sunuyor; ancak bu, senkronizasyon, aşırı görev parçalanması ve yürütme iş parçacıkları arasında eşit olmayan iş dağılımı gibi bazı ilginç sorunların çözülmesini gerektirecek.

C++ AMP çerçevesi ve diğer çok amaçlı GPU paralel hesaplama kitaplıkları, yüzlerce GPU çekirdeğindeki hesaplamaları paralelleştirmek için başarıyla kullanılabilir. Son olarak, son zamanlarda bilgi teknolojisinin geliştirilmesinde ana yönlerden biri haline gelen bulut dağıtılmış bilgi işlem teknolojilerinin kullanımından üretkenlik kazanımları elde etmek için daha önce keşfedilmemiş bir fırsat var.

GPU Hesaplama

CUDA teknolojisi (Compute Unified Device Architecture), GPGPU (video kartlarında rastgele bilgi işlem) teknolojisini destekleyen NVIDIA grafik işlemcilerini kullanarak bilgi işlem yapılmasına olanak tanıyan bir yazılım ve donanım mimarisidir. CUDA mimarisi ilk kez sekizinci nesil NVIDIA yongası G80'in piyasaya sürülmesiyle piyasaya çıktı ve GeForce, ION, Quadro ve Tesla hızlandırıcı ailelerinde kullanılan sonraki tüm grafik yonga serilerinde mevcut.

CUDA SDK, programcıların NVIDIA GPU'larda çalıştırılabilen algoritmaları C programlama dilinin özel, basitleştirilmiş bir lehçesinde uygulamasına ve bir C programının metnine özel işlevler eklemesine olanak tanır. CUDA, geliştiriciye, kendi takdirine bağlı olarak, grafik hızlandırıcının komut setine erişimi düzenleme ve belleğini yönetme ve bunun üzerinde karmaşık paralel hesaplamalar düzenleme fırsatı verir.

Hikaye

2003 yılında Intel ve AMD, en güçlü işlemciyi bulmak için ortak bir yarış içindeydi. Birkaç yıl boyunca bu yarışın bir sonucu olarak saat hızları, özellikle Intel Pentium 4'ün piyasaya sürülmesinden sonra önemli ölçüde arttı.

Saat frekanslarındaki artıştan sonra (2001 ile 2003 arasında Pentium 4'ün saat frekansı iki katına çıkarak 1,5 GHz'den 3 GHz'e çıktı) ve kullanıcılar, üreticiler tarafından pazara sunulan onda bir gigahertz ile yetinmek zorunda kaldı (2003'ten 2005'e, saat frekansları 3'ten 3,8 GHz'e yükseldi).

Prescott gibi yüksek saat frekansları için optimize edilmiş mimariler de yalnızca üretimde değil, zorluklarla karşılaşmaya başladı. Çip üreticileri fizik yasalarının üstesinden gelmede zorluklarla karşı karşıyadır. Hatta bazı analistler Moore Yasasının artık geçerli olmayacağını tahmin ediyordu. Ancak bu gerçekleşmedi. Yasanın orijinal anlamı sıklıkla çarpıtılıyor ancak bu, silikon çekirdeğin yüzeyindeki transistörlerin sayısıyla ilgili. Uzun bir süre, CPU'daki transistör sayısındaki artışa performansta da karşılık gelen bir artış eşlik etti ve bu da anlamın bozulmasına yol açtı. Ancak daha sonra durum daha da karmaşıklaştı. CPU mimarisinin geliştiricileri, büyümedeki azalma yasasına yaklaştı: Performansta gerekli artış için eklenmesi gereken transistörlerin sayısı giderek arttı ve bu da bir çıkmaza yol açtı.

GPU üreticilerinin bu sorunla karşılaşmamasının nedeni çok basit: CPU'lar, farklı verileri (hem tamsayı hem de kayan nokta sayıları) işleyen, rastgele bellek erişimi vb. gerçekleştiren bir talimat akışında maksimum performans elde etmek üzere tasarlanmıştır. d. Şimdiye kadar geliştiriciler, talimatlar arasında daha fazla paralellik sağlamaya, yani mümkün olduğu kadar çok talimatı paralel olarak yürütmeye çalışıyorlar. Örneğin, Pentium'da, belirli koşullar altında saat döngüsü başına iki talimatın yürütülmesi mümkün olduğunda süperskalar yürütme ortaya çıktı. Pentium Pro, bilgi işlem birimlerinin çalışmasını optimize etmeyi mümkün kılan talimatların sıra dışı yürütülmesini aldı. Sorun şu ki, sıralı bir talimat akışını paralel olarak yürütmenin bariz sınırlamaları vardır, bu nedenle hesaplama birimlerinin sayısını körü körüne arttırmak, çoğu zaman hala boşta kalacakları için herhangi bir fayda sağlamaz.

GPU'nun çalışması nispeten basittir. Bir tarafta bir grup çokgen alıp diğer tarafta bir grup piksel oluşturmaktan oluşur. Çokgenler ve pikseller birbirinden bağımsız olduğundan paralel olarak işlenebilirler. Böylece, bir GPU'da kristalin büyük bir kısmını, CPU'nun aksine gerçekte kullanılacak olan hesaplama birimlerine tahsis etmek mümkündür.

GPU ile CPU arasındaki tek fark bu değildir. GPU'daki bellek erişimi çok bağlantılıdır; eğer bir doku okunursa, birkaç saat döngüsünden sonra komşu doku da okunacaktır; Bir piksel kaydedildiğinde, birkaç saat döngüsünden sonra komşusu kaydedilecektir. Belleği akıllıca düzenleyerek teorik verime yakın bir performans elde edebilirsiniz. Bu, GPU'nun CPU'dan farklı olarak çok büyük bir önbellek gerektirmediği anlamına gelir çünkü rolü dokulandırma işlemlerini hızlandırmaktır. İhtiyaç duyulan tek şey, çift doğrusal ve üç doğrusal filtrelerde kullanılan birkaç tekseli içeren birkaç kilobayttır.

GPU'da ilk hesaplamalar

Bu tür uygulamalara yönelik ilk girişimler, rasterleştirme ve Z-tamponlama gibi belirli donanım işlevlerinin kullanımıyla sınırlıydı. Ancak içinde bulunduğumuz yüzyılda gölgelendiricilerin ortaya çıkmasıyla matris hesaplamaları hızlanmaya başladı. 2003 yılında SIGGRAPH'ta GPU hesaplama için ayrı bir bölüm ayrıldı ve buna GPGPU (GPU'da Genel Amaçlı hesaplama) adı verildi.

En iyi bilineni, Brook akışlı programlama dilinin derleyicisi olan ve GPU üzerinde grafiksel olmayan hesaplamalar gerçekleştirmek üzere tasarlanmış BrookGPU'dur. Ortaya çıkmadan önce, hesaplamalar için video çiplerinin yeteneklerini kullanan geliştiriciler iki ortak API'den birini seçiyordu: Direct3D veya OpenGL. Bu, GPU'ların kullanımını ciddi şekilde sınırladı çünkü 3D grafikler, paralel programlama uzmanlarının bilmesinin gerekmediği gölgelendiriciler ve dokular kullanıyor; bunlar iş parçacıklarını ve çekirdekleri kullanıyor. Brook işlerini kolaylaştırmaya yardımcı oldu. Stanford Üniversitesi'nde geliştirilen C diline yönelik bu akış uzantıları, 3D API'yi programcılardan gizledi ve video çipini paralel bir yardımcı işlemci olarak sundu. Derleyici, C++ kodu ve uzantılarına sahip .br dosyasını işleyerek DirectX, OpenGL veya x86 özellikli bir kitaplığa bağlı kod üretti.

Brook'un ortaya çıkışı NVIDIA ve ATI arasında ilgi uyandırdı ve ardından tamamen yeni bir sektör açtı: video çiplerine dayalı paralel bilgisayarlar.

Daha sonra Brook projesinden bazı araştırmacılar, donanım-yazılım paralel hesaplama stratejisini tanıtmak ve yeni pazar payı açmak üzere NVIDIA geliştirme ekibine geçti. Ve bu NVIDIA girişiminin ana avantajı, geliştiricilerin GPU'larının tüm yeteneklerini en ince ayrıntısına kadar bilmeleri ve grafik API'sini kullanmaya gerek olmaması ve sürücüyü kullanarak donanımla doğrudan çalışabilmenizdir. Bu ekibin çabalarının sonucu NVIDIA CUDA oldu.

GPU'da paralel hesaplamaların uygulama alanları

Hesaplamaları GPU'ya aktarırken birçok görev, hızlı genel amaçlı işlemcilere kıyasla 5-30 kat hızlanma elde eder. En büyük sayılara (100 kat hızlanma ve hatta daha fazlası!), SSE blokları kullanılarak yapılan hesaplamalar için pek uygun olmayan ancak GPU'lar için oldukça uygun olan kodla ulaşılır.

Bunlar, GPU'daki sentetik koda karşılık CPU'daki SSE-vektörize koda yönelik hızlandırmaların yalnızca birkaç örneğidir (NVIDIA'ya göre):

Floresan mikroskobu: 12x.

Moleküler dinamik (bağlanmamış kuvvet hesabı): 8-16x;

Elektrostatik (doğrudan ve çok düzeyli Coulomb toplamı): 40-120x ve 7x.

NVIDIA'nın tüm sunumlarda gösterdiği bir tablo, GPU'ların CPU'lara göre hızını gösterir.

GPU hesaplamanın kullanıldığı ana uygulamaların listesi: görüntü ve sinyallerin analizi ve işlenmesi, fizik simülasyonu, hesaplamalı matematik, hesaplamalı biyoloji, finansal hesaplamalar, veritabanları, gaz ve sıvı dinamiği, kriptografi, uyarlanabilir radyasyon terapisi, astronomi, ses işleme , biyoinformatik, biyolojik simülasyonlar, bilgisayarlı görme, veri madenciliği, dijital sinema ve televizyon, elektromanyetik simülasyonlar, coğrafi bilgi sistemleri, askeri uygulamalar, maden planlaması, moleküler dinamik, manyetik rezonans görüntüleme (MRI), sinir ağları, oşinografik araştırma, parçacık fiziği, protein katlanma simülasyonu, kuantum kimyası, ışın izleme, görselleştirme, radar, rezervuar simülasyonu, yapay zeka, uydu veri analizi, sismik keşif, cerrahi, ultrason, video konferans.

CUDA'nın Avantajları ve Sınırlamaları

Bir programcının bakış açısına göre grafik boru hattı, işleme aşamalarının bir koleksiyonudur. Geometri bloğu üçgenleri oluşturur ve rasterleştirme bloğu monitörde görüntülenen pikselleri oluşturur. Geleneksel GPGPU programlama modeli şuna benzer:

Bu modelde hesaplamaların GPU'ya aktarılması için özel bir yaklaşıma ihtiyaç vardır. İki vektörün eleman bazında eklenmesi bile, şeklin ekrana veya ekran dışı bir ara belleğe çizilmesini gerektirecektir. Şekil rasterleştirilir, her pikselin rengi belirli bir program (piksel gölgelendirici) kullanılarak hesaplanır. Program, her piksel için dokulardan giriş verilerini okur, bunları ekler ve çıkış arabelleğine yazar. Ve tüm bu sayısız işlemler, normal bir programlama dilinde tek bir operatörle yazılan bir şey için gereklidir!

Bu nedenle, GPGPU'nun genel amaçlı hesaplama için kullanılması, geliştiricilerin eğitilmesinin çok zor olması sınırlamasına sahiptir. Ve başka kısıtlamalar da var, çünkü bir piksel gölgelendirici yalnızca bir pikselin son renginin koordinatına bağımlılığına ilişkin bir formüldür ve piksel gölgelendiricilerin dili, bu formülleri C benzeri bir sözdizimiyle yazmak için kullanılan bir dildir. İlk GPGPU yöntemleri, GPU'nun gücünü kullanmanıza olanak tanıyan, ancak hiçbir kolaylık sağlamayan güzel bir numaradır. Buradaki veriler görüntülerle (dokular) temsil edilir ve algoritma, rasterleştirme işlemiyle temsil edilir. Bellek ve yürütmenin çok özel modeli özellikle dikkat çekicidir.

NVIDIA'nın GPU hesaplamaya yönelik yazılım ve donanım mimarisi, standart sözdizimi, işaretçiler ve video çiplerinin bilgi işlem kaynaklarına erişmek için minimum uzantı ihtiyacı ile GPU için gerçek C dilinde programlar yazmanıza olanak sağlaması açısından önceki GPGPU modellerinden farklıdır. CUDA, grafik API'lerinden bağımsızdır ve genel amaçlı bilgi işlem için özel olarak tasarlanmış bazı özelliklere sahiptir.

CUDA'nın GPGPU bilişime geleneksel yaklaşıma göre avantajları

CUDA, çoklu işlemci başına 16 KB iş parçacığı paylaşımlı belleğe erişim sağlar; bu, doku getirmelerden daha yüksek bant genişliğine sahip bir önbellek düzenlemek için kullanılabilir;

Sistem ve video belleği arasında daha verimli veri aktarımı;

Artıklık ve ek yük içeren grafiksel API'lere gerek yok;

Doğrusal bellek adresleme, toplama ve dağıtma, isteğe bağlı adreslere yazma yeteneği;

Tam sayı ve bit işlemleri için donanım desteği.

CUDA'nın ana sınırlamaları:

Yürütülebilir işlevler için özyineleme desteğinin olmaması;

Minimum blok genişliği 32 iş parçacığıdır;

NVIDIA'ya ait kapalı CUDA mimarisi.

Önceki GPGPU yöntemleriyle programlamanın zayıf yönleri, bu yöntemlerin önceki birleşik olmayan mimarilerde köşe gölgelendirici yürütme birimlerini kullanmaması, verilerin dokularda saklanması ve ekran dışı bir ara belleğe çıktı olarak alınması ve çok geçişli algoritmaların piksel gölgelendirici birimleri kullanmasıdır. GPGPU sınırlamaları şunları içerebilir: donanım özelliklerinin yetersiz kullanımı, bellek bant genişliği sınırlamaları, dağılım işleminin eksikliği (yalnızca toplama), grafik API'sinin zorunlu kullanımı.

CUDA'nın önceki GPGPU yöntemlerine göre ana avantajları, mimarinin GPU'da grafik olmayan hesaplamayı verimli bir şekilde kullanacak şekilde tasarlanmış olması ve algoritmaların konsept dostu bir grafik hattına taşınmasını gerektirmeden C programlama dilini kullanması gerçeğinden kaynaklanmaktadır. . CUDA, grafik API'lerini kullanmayan, rastgele bellek erişimi (dağılım veya toplama) sunan GPU hesaplamaya yeni bir yol sunar. Bu mimari, GPGPU'nun dezavantajlarına sahip değildir ve tüm yürütme birimlerini kullanır, ayrıca tamsayı matematiği ve bit kaydırma işlemleri nedeniyle yetenekleri genişletir.

CUDA, paylaşılan bellek gibi grafik API'lerinde bulunmayan bazı donanım yeteneklerini açar. Bu, iş parçacığı bloklarının erişebildiği küçük bir bellektir (çoklu işlemci başına 16 kilobayt). En sık erişilen verileri önbelleğe almanıza olanak tanır ve bu görev için doku getirmeyi kullanmaktan daha yüksek hızlar sağlayabilir. Bu da birçok uygulamada paralel algoritmaların verim hassasiyetini azaltır. Örneğin doğrusal cebir, hızlı Fourier dönüşümü ve görüntü işleme filtreleri için kullanışlıdır.

CUDA'da belleğe erişim de daha uygundur. Grafik API kodu, verileri önceden tanımlanmış alanlara 32 tek duyarlıklı kayan nokta değeri (RGBA değerleri aynı anda sekiz oluşturma hedefi halinde) olarak çıkarır ve CUDA, herhangi bir adreste sınırsız sayıda kayıt olan dağılım yazmayı destekler. Bu tür avantajlar, grafik API'lerine dayalı GPGPU yöntemleri kullanılarak verimli bir şekilde uygulanamayan bazı algoritmaların GPU üzerinde yürütülmesini mümkün kılar.

Ayrıca, grafik API'leri verileri zorunlu olarak dokularda depolar; bu da büyük dizilerin dokular halinde önceden paketlenmesini gerektirir, bu da algoritmayı karmaşıklaştırır ve özel adreslemenin kullanılmasını zorlar. Ve CUDA, herhangi bir adresteki verileri okumanıza olanak tanır. CUDA'nın bir diğer avantajı CPU ve GPU arasındaki optimize edilmiş veri alışverişidir. Ve düşük seviyeli erişim isteyen geliştiriciler için (örneğin başka bir programlama dili yazarken), CUDA düşük seviyeli montaj dili programlama yetenekleri sunar.

CUDA'nın dezavantajları

CUDA'nın birkaç dezavantajından biri taşınabilirliğinin zayıf olmasıdır. Bu mimari yalnızca bu şirketin video çipleri üzerinde çalışıyor; hepsinde değil, GeForce 8 ve 9 serisinden ve ilgili Quadro, ION ve Tesla'dan başlayarak. NVIDIA 90 milyon CUDA uyumlu video yongası rakamından bahsediyor.

CUDA Alternatifleri

Çeşitli grafikler ve merkezi işlemciler üzerinde paralel hesaplamayla ilgili bilgisayar programlarının yazılmasına yönelik bir çerçeve. OpenCL çerçevesi, C99 standardını temel alan bir programlama dili ve bir uygulama programlama arayüzü (API) içerir. OpenCL, talimat düzeyinde ve veri düzeyinde paralellik sağlar ve GPGPU tekniğinin bir uygulamasıdır. OpenCL tamamen açık bir standarttır ve kullanımı telifsizdir.

OpenCL'in amacı, GPU'nun gücünden yararlanarak 3D bilgisayar grafikleri ve ses için açık endüstri standartları olan OpenGL ve OpenAL'i tamamlamaktır. OpenCL, Apple, AMD, Intel, nVidia, Sun Microsystems, Sony Computer Entertainment ve diğerleri dahil olmak üzere birçok büyük şirketi içeren, kar amacı gütmeyen bir konsorsiyum olan Khronos Group tarafından geliştirilmekte ve sürdürülmektedir.

CAL/IL(Hesaplama Soyutlama Katmanı/Ara Dil)

ATI Stream Teknolojisi, AMD GPU'ların bir CPU ile birlikte kullanılarak birçok uygulamayı (yalnızca grafikleri değil) hızlandırmasını sağlayan bir dizi donanım ve yazılım teknolojisidir.

ATI Stream uygulamaları, finansal analiz veya sismik veri işleme gibi hesaplama açısından yoğun uygulamaları içerir. Bir akış işlemcisinin kullanılması, bazı finansal hesaplamaların hızını, aynı sorunun yalnızca merkezi işlemci kullanılarak çözülmesine kıyasla 55 kat artırmayı mümkün kıldı.

NVIDIA, ATI Stream teknolojisini çok güçlü bir rakip olarak görmüyor. CUDA ve Stream, farklı gelişim seviyelerinde olan iki farklı teknolojidir. ATI ürünleri için programlama çok daha karmaşıktır; dilleri daha çok montaj diline benzer. CUDA C ise çok daha üst düzey bir dildir. Üzerine yazmak daha rahat ve kolaydır. Bu büyük geliştirme şirketleri için çok önemlidir. Performanstan bahsedecek olursak ATI ürünlerindeki tepe değerinin NVIDIA çözümlerine göre daha yüksek olduğunu görebiliriz. Ama yine de mesele bu gücün nasıl elde edileceğine bağlı.

DirectX11 (DirectCompute)

Microsoft Windows işletim sistemlerini çalıştıran IBM PC uyumlu bilgisayarlarda çalışmak üzere tasarlanmış, Microsoft'un bir dizi API'si olan DirectX'in parçası olan bir uygulama programlama arabirimi. DirectCompute, GPGPU konseptinin bir uygulaması olan GPU'lar üzerinde genel amaçlı bilgi işlem gerçekleştirmek üzere tasarlanmıştır. DirectCompute ilk olarak DirectX 11'in bir parçası olarak yayınlandı ancak daha sonra DirectX 10 ve DirectX 10.1 için kullanılabilir hale geldi.

Rus bilim camiasında NVDIA CUDA.

Aralık 2009 itibarıyla CUDA yazılım modeli dünya çapında 269 üniversitede öğretilmektedir. Rusya'da Moskova, St. Petersburg, Kazan, Novosibirsk ve Perm Devlet Üniversiteleri, Uluslararası Toplum Doğası Üniversitesi ve Man "Dubna", Ortak Nükleer Araştırma Enstitüsü, Moskova Elektronik Enstitüsü'nde CUDA ile ilgili eğitim kursları verilmektedir. Teknoloji, Ivanovo Devlet Enerji Üniversitesi, BSTU. V. G. Shukhov, MSTU im. Bauman, Rusya Kimya Teknik Üniversitesi'nin adını almıştır. Mendeleev, Rusya Bilim Merkezi "Kurchatov Enstitüsü", Rusya Bilimler Akademisi Bölgelerarası Süper Bilgisayar Merkezi, Taganrog Teknoloji Enstitüsü (TTI SFU).

Bir zamanlar bilgisayar pazarında dizüstü bilgisayar satan birçok şirketten birinin teknik müdürüyle konuşma şansım olmuştu. Bu "uzman" ağzından köpükler saçarak tam olarak hangi dizüstü bilgisayar konfigürasyonuna ihtiyacım olduğunu açıklamaya çalıştı. Monologunun ana mesajı, merkezi işlem birimlerinin (CPU'lar) zamanının sona erdiği ve artık tüm uygulamaların grafik işlemci (GPU) üzerindeki hesaplamaları aktif olarak kullandığı ve bu nedenle bir dizüstü bilgisayarın performansının tamamen GPU'ya bağlı olduğu ve siz CPU dikkatine herhangi bir dikkat vermenize gerek yok. Bu teknik direktörle tartışmanın, mantık yürütmenin anlamsız olduğunu anlayınca vakit kaybetmedim ve ihtiyacım olan laptopu başka bir pavyondan aldım. Ancak satıcının bu kadar bariz beceriksizliği beni şaşırttı. Eğer alıcı olarak beni kandırmaya çalışıyorsa bu anlaşılır olurdu. Hiç de bile. Söylediklerine içtenlikle inanıyordu. Evet, görünüşe göre, NVIDIA ve AMD'deki pazarlamacılar ekmeklerini bir nedenden dolayı yiyorlar ve bazı kullanıcılara grafik işlemcinin modern bir bilgisayardaki baskın rolü fikrini aşılamayı başardılar.

Grafik işlem birimi (GPU) bilişiminin günümüzde giderek daha popüler hale gelmesi şüphe götürmez bir gerçektir. Ancak bu, merkezi işlemcinin rolünü hiçbir şekilde azaltmaz. Üstelik kullanıcı uygulamalarının büyük çoğunluğundan bahsedersek, bugün bunların performansı tamamen CPU'nun performansına bağlıdır. Yani, kullanıcı uygulamalarının büyük çoğunluğu GPU hesaplamayı kullanmamaktadır.

Genel olarak GPU hesaplama, bilimsel hesaplamaya yönelik özel HPC sistemlerinde gerçekleştirilir. Ancak GPU hesaplamayı kullanan kullanıcı uygulamaları bir yandan sayılabilir. Bu durumda "GPU hesaplama" teriminin tamamen doğru olmadığı ve yanıltıcı olabileceği hemen belirtilmelidir. Gerçek şu ki, eğer bir uygulama GPU hesaplamayı kullanıyorsa, bu merkezi işlemcinin boşta olduğu anlamına gelmez. GPU hesaplama, yükün merkezi işlemciden grafik işlemciye aktarılmasını içermez. Kural olarak, merkezi işlemci meşgul kalır ve grafik işlemcinin merkezi işlemciyle birlikte kullanılması performansı artırabilir, yani bir görevi tamamlamak için gereken süreyi azaltabilir. Dahası, GPU'nun kendisi burada CPU için bir tür yardımcı işlemci görevi görür, ancak hiçbir durumda onun tamamen yerini almaz.

GPU hesaplamanın neden her derde deva olmadığını ve hesaplama yeteneklerinin CPU'nunkini aştığını söylemenin neden yanlış olduğunu anlamak için, merkezi işlemci ile grafik işlemci arasındaki farkı anlamak gerekir.

GPU ve CPU mimarilerindeki farklılıklar

CPU çekirdekleri, maksimum performansta tek bir sıralı talimat akışını yürütmek üzere tasarlanırken, GPU çekirdekleri çok sayıda paralel talimat akışını hızlı bir şekilde yürütmek üzere tasarlanmıştır. GPU'lar ile merkezi işlemciler arasındaki temel fark budur. CPU, hem tamsayı hem de kayan nokta sayılarını işleyen tek bir talimat akışından yüksek performans elde etmek üzere optimize edilmiş genel amaçlı veya genel amaçlı bir işlemcidir. Bu durumda veri ve talimatların bulunduğu belleğe erişim ağırlıklı olarak rastgele gerçekleşir.

CPU performansını artırmak için mümkün olduğu kadar çok talimatı paralel olarak yürütecek şekilde tasarlanmıştır. Örneğin, bu amaçla, işlemci çekirdekleri, talimatların geliş sırasına göre yeniden düzenlenmesini mümkün kılan, bu da komutların uygulanmasındaki paralellik düzeyinin artırılmasını mümkün kılan sıra dışı bir talimat yürütme birimi kullanır. tek iş parçacığı düzeyinde talimatlar. Ancak bu yine de çok sayıda talimatın paralel yürütülmesine izin vermez ve işlemci çekirdeği içindeki talimatların paralelleştirilmesinin getirdiği yük çok önemli olur. Genel amaçlı işlemcilerin çok fazla sayıda yürütme birimine sahip olmamasının nedeni budur.

Grafik işlemcisi temelde farklı şekilde tasarlanmıştır. Başlangıçta çok sayıda paralel komut akışını çalıştırmak için tasarlandı. Üstelik bu komut akışları başlangıçtan itibaren paralelleştirilir ve GPU'daki talimatları paralelleştirmenin genel maliyetleri yoktur. GPU görüntüleri işlemek için tasarlanmıştır. Basitçe açıklamak gerekirse, girdi olarak bir grup çokgeni alır, gerekli tüm işlemleri gerçekleştirir ve çıktı olarak pikseller üretir. Çokgenlerin ve piksellerin işlenmesi bağımsızdır; paralel olarak, birbirlerinden ayrı olarak işlenebilirler. Bu nedenle, işin doğası gereği paralel organizasyonu nedeniyle GPU, CPU için sıralı talimat akışının aksine, yüklenmesi kolay çok sayıda yürütme birimi kullanır.

Grafikler ve merkezi işlemciler de bellek erişimi ilkeleri açısından farklılık gösterir. Bir GPU'da belleğe erişim kolaylıkla tahmin edilebilir: eğer bir doku dokusu bellekten okunursa, bir süre sonra komşu dokular için son tarih gelecektir. Kayıt sırasında da aynı şey olur: Çerçeve arabelleğine bir piksel yazılırsa, birkaç saat döngüsünden sonra yanında bulunan piksel yazılacaktır. Bu nedenle GPU, CPU'nun aksine büyük bir önbelleğe ihtiyaç duymaz ve dokular yalnızca birkaç kilobayt gerektirir. Bellekle çalışma prensibi GPU'lar ve CPU'lar için de farklıdır. Dolayısıyla, tüm modern GPU'larda birden fazla bellek denetleyicisi bulunur ve grafik belleğinin kendisi daha hızlıdır, dolayısıyla GPU'larda çok daha fazlası vardır. O evrensel işlemcilere kıyasla daha büyük bellek bant genişliği; bu da büyük veri akışlarıyla çalışan paralel hesaplamalar için çok önemlidir.

Üniversal işlemcilerde OÇip alanının çoğu, çeşitli komut ve veri arabellekleri, kod çözme birimleri, donanım dal tahmin birimleri, talimat yeniden sıralama birimleri ve birinci, ikinci ve üçüncü seviyelerin önbellekleri tarafından işgal edilir. Tüm bu donanım birimleri, birkaç komut iş parçacığının işlemci çekirdeği düzeyinde paralel hale getirilerek yürütülmesini hızlandırmak için gereklidir.

Yürütme birimlerinin kendisi evrensel bir işlemcide nispeten az yer kaplar.

Bir grafik işlemcide ise tam tersine, ana alan çok sayıda yürütme birimi tarafından işgal edilir ve bu da onun aynı anda birkaç bin komut iş parçacığını işlemesine olanak tanır.

GPU'ların modern CPU'lardan farklı olarak çok sayıda aritmetik işlem içeren paralel hesaplamalar için tasarlandığını söyleyebiliriz.

GPU'ların bilgi işlem gücünü grafiksel olmayan görevler için kullanmak mümkündür, ancak yalnızca çözülen problemin GPU'da bulunan yüzlerce yürütme biriminde algoritmaların paralelleştirilmesi olasılığına izin vermesi durumunda. Özellikle GPU hesaplamaları, aynı matematiksel işlem sırası büyük miktarda veriye uygulandığında mükemmel sonuçlar verir. Bu durumda en iyi sonuçlar, aritmetik komut sayısının hafıza erişim sayısına oranının yeterince büyük olması durumunda elde edilir. Bu işlem daha az yürütme kontrolü gerektirir ve büyük önbellek gerektirmez.

Hesaplama verimliliği açısından GPU'nun CPU üzerindeki avantajının yadsınamaz olduğu birçok bilimsel hesaplama örneği vardır. Bu nedenle, moleküler modelleme, gaz dinamiği, akışkanlar dinamiği ve diğer alanlardaki birçok bilimsel uygulama, GPU'daki hesaplamalar için mükemmel şekilde uygundur.

Dolayısıyla, bir sorunu çözmeye yönelik algoritma binlerce ayrı iş parçacığına paralel hale getirilebilirse, böyle bir sorunu GPU kullanarak çözmenin verimliliği, yalnızca genel amaçlı bir işlemci kullanarak çözmekten daha yüksek olabilir. Bununla birlikte, CPU ve GPU'nun farklı komutlar kullanması nedeniyle bazı sorunların çözümünü CPU'dan GPU'ya bu kadar kolay aktaramazsınız. Yani, CPU üzerinde bir çözüm için program yazıldığında x86 komut seti (veya belirli bir işlemci mimarisiyle uyumlu bir komut seti) kullanılır, ancak GPU için yine tamamen farklı komut setleri kullanılır. mimarisini ve yeteneklerini hesaba katın. Modern 3D oyunlar geliştirirken programcıların gölgelendiriciler ve dokularla çalışmasına olanak tanıyan DirectX ve OpenGL API'leri kullanılır. Ancak GPU'da grafiksel olmayan bilgi işlem için DirectX ve OpenGL API'lerini kullanmak en iyi seçenek değildir.

NVIDIA CUDA ve AMD UYGULAMASI

Bu nedenle, GPU'da (Genel Amaçlı GPU, GPGPU) grafiksel olmayan hesaplamayı uygulamaya yönelik ilk girişimler başladığında BrookGPU derleyicisi ortaya çıktı. Geliştiriciler, oluşturulmadan önce OpenGL veya Direct3D grafik API'si aracılığıyla video kartı kaynaklarına erişmek zorundaydı; bu, özel bilgi gerektirdiğinden programlama sürecini önemli ölçüde karmaşıklaştırdı - 3D nesnelerle (gölgelendiriciler, dokular vb.) çalışma ilkelerini öğrenmek zorunda kaldılar. ). GPGPU'nun yazılım ürünlerinde çok sınırlı kullanılmasının nedeni buydu. BrookGPU bir tür “çevirmen” haline geldi. C diline yapılan bu akış uzantıları, 3D API'yi programcılardan sakladı ve bunu kullanırken, 3D programlama bilgisine olan ihtiyaç neredeyse ortadan kalktı. Video kartlarının bilgi işlem gücü, paralel hesaplamalar için ek bir yardımcı işlemci biçiminde programcıların kullanımına sunuldu. BrookGPU derleyicisi dosyayı C kodu ve uzantılarıyla işleyerek kodu DirectX veya OpenGL destekli bir kitaplığa bağladı.

Büyük ölçüde BrookGPU sayesinde, NVIDIA ve ATI (şimdi AMD), GPU'larda ortaya çıkan genel amaçlı bilgi işlem teknolojisini fark etti ve 3D hızlandırıcıların bilgi işlem birimlerine doğrudan ve daha şeffaf erişim sağlayan kendi uygulamalarını geliştirmeye başladı.

Sonuç olarak NVIDIA, paralel hesaplama için CUDA (Compute Unified Device Architecture) adlı bir donanım ve yazılım mimarisi geliştirdi. CUDA mimarisi, NVIDIA GPU'larda grafik olmayan bilgi işlemi mümkün kılar.

CUDA SDK'nın genel beta sürümünün piyasaya sürülmesi Şubat 2007'de gerçekleşti. CUDA API, C dilinin basitleştirilmiş bir lehçesine dayanmaktadır. CUDA SDK mimarisi, programcıların NVIDIA GPU'lar üzerinde çalışan algoritmaları uygulamasına ve C program metnine özel işlevler eklemesine olanak tanır. Kodu bu dile başarıyla çevirmek için CUDA SDK, NVIDIA'nın kendi nvcc komut satırı derleyicisini içerir.

CUDA, Linux, Mac OS X ve Windows gibi işletim sistemleri için platformlar arası bir yazılımdır.

AMD (ATI), daha önce ATI Stream ve şimdi AMD Hızlandırılmış Paralel İşleme (APP) olarak adlandırılan GPGPU teknolojisinin kendi sürümünü de geliştirdi. AMD APP, açık endüstri standardı OpenCL'i (Açık Bilgi İşlem Dili) temel alır. OpenCL standardı, talimat düzeyinde ve veri düzeyinde paralellik sağlar ve GPGPU tekniğinin bir uygulamasıdır. Tamamen açık bir standarttır ve kullanımı telifsizdir. AMD APP ve NVIDIA CUDA'nın birbiriyle uyumlu olmadığını ancak NVIDIA CUDA'nın en son sürümünün OpenCL'yi de desteklediğini unutmayın.

Video dönüştürücülerde GPGPU'yu test etme

Böylece, NVIDIA GPU'larda GPGPU'yu uygulamak için CUDA teknolojisinin kullanıldığını ve AMD GPU'larda APP API'nin kullanıldığını öğrendik. Daha önce belirtildiği gibi, GPU'da grafiksel olmayan hesaplamanın kullanılması, yalnızca çözülen problemin birçok iş parçacığına paralel hale getirilebilmesi durumunda tavsiye edilir. Ancak çoğu kullanıcı uygulaması bu kriteri karşılamamaktadır. Ancak bazı istisnalar da vardır. Örneğin, çoğu modern video dönüştürücü, NVIDIA ve AMD GPU'larda bilgi işlem kullanma yeteneğini destekler.

Özel video dönüştürücülerde GPU hesaplamanın ne kadar verimli kullanıldığını bulmak için üç popüler çözüm seçtik: Xilisoft Video Converter Ultimate 7.7.2, Wondershare Video Converter Ultimate 6.0.3.2 ve Movavi Video Converter 10.2.1. Bu dönüştürücüler, NVIDIA ve AMD GPU'larını kullanma yeteneğini destekler ve bu özelliği, GPU kullanmanın etkinliğini değerlendirmenize olanak tanıyan video dönüştürücü ayarlarında devre dışı bırakabilirsiniz.

Video dönüşümü için üç farklı video kullandık.

İlk video 3 dakika 35 saniye uzunluğunda ve 1,05 GB boyutundaydı. Mkv veri depolama formatında (konteyner) kaydedilmiştir ve aşağıdaki özelliklere sahiptir:

  • video:
    • formatı - MPEG4 Video (H264),
    • çözünürlük - 1920*um*1080,
    • bit hızı modu - Değişken,
    • ortalama video bit hızı - 42,1 Mbit/s,
    • maksimum video bit hızı - 59,1 Mbit/s,
    • kare hızı - 25 fps;
  • ses:
    • formatı - MPEG-1 Ses,
    • ses bit hızı - 128 Kbps,
    • kanal sayısı - 2,

İkinci video ise 4 dakika 25 saniye uzunluğunda ve 1,98 GB boyutundaydı. MPG veri depolama formatında (konteyner) kaydedilmiştir ve aşağıdaki özelliklere sahiptir:

  • video:
    • formatı - MPEG-PS (MPEG2 Video),
    • çözünürlük - 1920*um*1080,
    • bit hızı modu - Değişken.
    • ortalama video bit hızı - 62,5 Mbit/s,
    • maksimum video bit hızı - 100 Mbit/s,
    • kare hızı - 25 fps;
  • ses:
    • formatı - MPEG-1 Ses,
    • ses bit hızı - 384 Kbps,
    • kanal sayısı - 2,

Üçüncü video ise 3 dakika 47 saniye uzunluğunda ve 197 MB boyutundaydı. MOV veri depolama formatında (konteyner) yazılmıştır ve aşağıdaki özelliklere sahiptir:

  • video:
    • formatı - MPEG4 Video (H264),
    • çözünürlük - 1920*um*1080,
    • bit hızı modu - Değişken,
    • video bit hızı - 7024 Kbps,
    • kare hızı - 25 fps;
  • ses:
    • format - AAC,
    • ses bit hızı - 256 Kbps,
    • kanal sayısı - 2,
    • örnekleme frekansı - 48 kHz.

Üç test videosunun tümü, iPad 2 tablette görüntülenmek üzere video dönüştürücüler kullanılarak MP4 veri depolama formatına (H.264 codec) dönüştürüldü. Çıkış video dosyasının çözünürlüğü 1280*um*720 idi.

Her üç dönüştürücüde de tamamen aynı dönüştürme ayarlarını kullanmadığımızı lütfen unutmayın. Bu nedenle video dönüştürücülerin verimliliğini dönüşüm süresine göre karşılaştırmak yanlıştır. Bu nedenle, Xilisoft Video Converter Ultimate 7.7.2 video dönüştürücüsünde, dönüştürme için iPad 2 ön ayarı - H.264 HD Video kullanıldı. Bu ön ayar aşağıdaki kodlama ayarlarını kullanır:

  • codec bileşeni - MPEG4 (H.264);
  • çözünürlük - 1280*um*720;
  • kare hızı - 29,97 fps;
  • video bit hızı - 5210 Kbps;
  • ses codec bileşeni - AAC;
  • ses bit hızı - 128 Kbps;
  • kanal sayısı - 2;
  • örnekleme frekansı - 48 kHz.

Wondershare Video Converter Ultimate 6.0.3.2, aşağıdaki ek ayarlarla birlikte iPad 2 ön ayarını kullandı:

  • codec bileşeni - MPEG4 (H.264);
  • çözünürlük - 1280*um*720;
  • kare hızı - 30 fps;
  • video bit hızı - 5000 Kbps;
  • ses codec bileşeni - AAC;
  • ses bit hızı - 128 Kbps;
  • kanal sayısı - 2;
  • örnekleme frekansı - 48 kHz.

Movavi Video Converter 10.2.1, aşağıdaki ek ayarlarla birlikte iPad ön ayarını (1280*um*720, H.264) (*.mp4) kullandı:

  • video formatı - H.264;
  • çözünürlük - 1280*um*720;
  • kare hızı - 30 fps;
  • video bit hızı - 2500 Kbps;
  • ses codec bileşeni - AAC;
  • ses bit hızı - 128 Kbps;
  • kanal sayısı - 2;
  • örnekleme frekansı - 44,1 kHz.

Her kaynak video, hem GPU hem de yalnızca CPU kullanılarak video dönüştürücülerin her birinde beş kez dönüştürüldü. Her dönüşümden sonra bilgisayar yeniden başlatıldı.

Sonuç olarak her video, her video dönüştürücüde on kez dönüştürüldü. Bu rutin çalışmayı otomatikleştirmek için, test sürecini tamamen otomatikleştirmenize olanak tanıyan grafik arayüzlü özel bir yardımcı program yazılmıştır.

Test standı konfigürasyonu

Test standı aşağıdaki konfigürasyona sahipti:

  • işlemci - Intel Core i7-3770K;
  • anakart - Gigabyte GA-Z77X-UD5H;
  • anakart yonga seti - Intel Z77 Express;
  • bellek - DDR3-1600;
  • bellek kapasitesi - 8 GB (her biri 4 GB'lık iki GEIL modülü);
  • bellek çalışma modu - çift kanallı;
  • video kartı - NVIDIA GeForce GTX 660Ti (video sürücüsü 314.07);
  • sürücü - Intel SSD 520 (240 GB).

Standa Windows 7 Ultimate (64-bit) işletim sistemi kuruldu.

Başlangıçta işlemciyi ve diğer tüm sistem bileşenlerini normal modda test ettik. Aynı zamanda Intel Core i7-3770K işlemci, Turbo Boost modu etkinken standart 3,5 GHz frekansta çalışıyordu (Turbo Boost modunda maksimum işlemci frekansı 3,9 GHz'dir).

Daha sonra test sürecini tekrarladık, ancak işlemciyi 4,5 GHz'lik sabit bir frekansa (Turbo Boost modunu kullanmadan) hız aşırtmayla çalıştırdık. Bu, dönüşüm hızının işlemci frekansına (CPU) bağımlılığını tanımlamayı mümkün kıldı.

Testin bir sonraki aşamasında standart işlemci ayarlarına geri döndük ve testleri diğer video kartlarıyla tekrarladık:

  • NVIDIA GeForce GTX 280 (sürücü 314.07);
  • NVIDIA GeForce GTX 460 (sürücü 314.07);
  • AMD Radeon HD6850 (sürücü 13.1).

Böylece farklı mimarilere sahip dört ekran kartı üzerinde video dönüştürme işlemi gerçekleştirildi.

Üst düzey NVIDIA GeForce 660Ti ekran kartı, 28 nm işlem teknolojisi kullanılarak üretilen, GK104 (Kepler mimarisi) kodlu aynı adlı bir grafik işlemcisine dayanmaktadır. Bu GPU 3,54 milyar transistör içeriyor ve 294 mm2 kalıp alanına sahip.

GK104 grafik işlemcisinin dört grafik işleme kümesi (Grafik İşleme Kümeleri, GPC) içerdiğini hatırlayın. GPC kümeleri işlemci içindeki bağımsız cihazlardır ve gerekli tüm kaynaklara sahip oldukları için ayrı cihazlar olarak çalışabilirler: rasterleştiriciler, geometri motorları ve doku modülleri.

Bu tür kümelerin her birinde iki adet SMX (Akış Çok İşlemcili) çok işlemci bulunur, ancak GK104 işlemcide kümelerden birinde bir çok işlemci engellenmiştir, dolayısıyla toplamda yedi SMX çok işlemcisi vardır.

Her SMX akışlı çoklu işlemci, 192 akışlı bilgi işlem çekirdeği (CUDA çekirdeği) içerir, dolayısıyla GK104 işlemcinin toplam 1344 CUDA çekirdeği vardır. Ek olarak, her bir SMX çoklu işlemcisi 16 doku birimi (TMU), 32 özel işlev birimi (SFU), 32 yük depolama birimi (LSU), bir PolyMorph motoru ve çok daha fazlasını içerir.

GeForce GTX 460, Fermi mimarisini temel alan GF104 kodlu bir GPU'yu temel alıyor. Bu işlemci 40nm işlem teknolojisi kullanılarak üretilmiştir ve yaklaşık 1,95 milyar transistör içerir.

GF104 GPU, iki GPC grafik işleme kümesi içerir. Her birinin dört SM akışlı çoklu işlemcisi vardır, ancak kümelerden birindeki GF104 işlemcide bir çoklu işlemci kilitlidir, dolayısıyla yalnızca yedi SM çoklu işlemcisi vardır.

Her SM akışlı çoklu işlemci, 48 akışlı bilgi işlem çekirdeği (CUDA çekirdeği) içerir, dolayısıyla GK104 işlemcinin toplam 336 CUDA çekirdeği vardır. Ek olarak, her bir SM çoklu işlemcisi sekiz doku birimi (TMU), sekiz özel işlev birimi (SFU), 16 yük depolama birimi (LSU), bir PolyMorph motoru ve çok daha fazlasını içerir.

GeForce GTX 280 GPU, NVIDIA Birleşik GPU Mimarisinin ikinci nesline aittir ve mimari olarak Fermi ve Kepler mimarisinden çok farklıdır.

GeForce GTX 280 GPU, benzer olmasına rağmen Fermi ve Kepler mimarilerindeki GPC grafik işleme kümelerinden çok farklı olan Doku İşleme Kümelerinden (TPC'ler) oluşur. GeForce GTX 280 işlemcide bu tür toplam on küme var. Her TPC kümesinde üç adet SM akışlı çoklu işlemci ve sekiz adet doku örnekleme ve filtreleme birimi (TMU) bulunur. Her çok işlemcili sekiz akış işlemcisinden (SP) oluşur. Çoklu işlemciler ayrıca hem grafiklerde hem de bazı hesaplama görevlerinde kullanılan doku verilerini örneklemek ve filtrelemek için birimler içerir.

Böylece, bir TPC kümesinde 24 akış işlemcisi var ve GeForce GTX 280 GPU'da zaten 240 tane var.

Testte kullanılan NVIDIA GPU'lardaki video kartlarının özet özellikleri tabloda sunulmaktadır.

Aşağıdaki tablo, teknik özelliklerinin NVIDIA ekran kartlarıyla karşılaştırılması zor olduğundan oldukça doğal olan AMD Radeon HD6850 ekran kartını içermemektedir. Bu nedenle bunu ayrı ayrı ele alacağız.

Barts kod adlı AMD Radeon HD6850 GPU, 40nm işlem teknolojisi kullanılarak üretiliyor ve 1,7 milyar transistör içeriyor.

AMD Radeon HD6850 işlemci mimarisi, birden fazla veri türünün akış halinde işlenmesi için bir dizi ortak işlemciden oluşan birleşik bir mimaridir.

AMD Radeon HD6850 işlemci, her biri 16 süperskalar akış işlemci birimi ve dört doku birimi içeren 12 SIMD çekirdeğinden oluşur. Her süperskalar akış işlemcisi beş genel amaçlı akış işlemcisi içerir. Böylece, toplamda AMD Radeon HD6850 GPU'da 12*um*16*um*5=960 evrensel akış işlemcisi bulunur.

AMD Radeon HD6850 ekran kartının GPU frekansı 775 MHz, etkin GDDR5 bellek frekansı ise 4000 MHz'dir. Bellek kapasitesi 1024 MB'tır.

Test sonuçları

Öyleyse test sonuçlarına bakalım. NVIDIA GeForce GTX 660Ti ekran kartını ve Intel Core i7-3770K işlemcinin standart çalışma modunu kullandığımız ilk testle başlayalım.

Şek. Şekil 1-3, GPU'lu ve GPU'suz modlarda üç dönüştürücü kullanarak üç test videosunu dönüştürmenin sonuçlarını gösterir.

Test sonuçlarından da anlaşılacağı üzere GPU kullanmanın etkisi ortadadır. Video dönüştürücü Xilisoft Video Converter Ultimate 7.7.2 için, GPU kullanıldığında dönüşüm süresi birinci, ikinci ve üçüncü video için sırasıyla %14, %9 ve %19 oranında azalır.

Wondershare Video Converter Ultimate 6.0.32 için GPU kullanmak, dönüşüm süresini birinci, ikinci ve üçüncü video için sırasıyla %10, %13 ve %23 oranında azaltır.

Ancak grafik işlemci kullanımından en fazla fayda sağlayan dönüştürücü Movavi Video Converter 10.2.1'dir. Birinci, ikinci ve üçüncü video için dönüşüm süresindeki azalma sırasıyla %64, %81 ve %41'dir.

GPU kullanmanın faydasının hem kaynak videoya hem de video dönüştürme ayarlarına bağlı olduğu açıktır; aslında sonuçlarımız da bunu göstermektedir.

Şimdi Intel Core i7-3770K işlemciyi 4,5 GHz'e hız aşırtırken dönüşüm süresi kazancının ne olacağını görelim. Normal modda tüm işlemci çekirdeklerinin dönüşüm sırasında yüklendiğini ve Turbo Boost modunda 3,7 GHz frekansında çalıştıklarını varsayarsak, frekansı 4,5 GHz'e çıkarmak %22 frekans hız aşırtmasına karşılık gelir.

Şek. Şekil 4-6, grafik işlemci kullanan ve içermeyen modlarda işlemciyi hız aşırtma sırasında üç test videosunu dönüştürmenin sonuçlarını göstermektedir. Bu durumda grafik işlemcinin kullanılması dönüşüm süresinde kazanç sağlar.

Video dönüştürücü Xilisoft Video Converter Ultimate 7.7.2 için, GPU kullanıldığında dönüşüm süresi birinci, ikinci ve üçüncü video için sırasıyla %15, %9 ve %20 azalır.

Wondershare Video Converter Ultimate 6.0.32 için, GPU kullanmak birinci, ikinci ve üçüncü video için dönüşüm süresini sırasıyla %10, %10 ve %20 oranında azaltabilir.

Movavi Video Converter 10.2.1 için grafik işlemci kullanımı dönüşüm süresini sırasıyla %59, %81 ve %40 oranında azaltabilir.

Doğal olarak, CPU hız aşırtma işleminin GPU varken ve GPU olmadan dönüşüm sürelerini nasıl azaltabildiğini görmek ilginç.

Şek. Şekil 7-9, normal işlemci modunda ve hız aşırtma modunda grafik işlemci kullanmadan videoları dönüştürme süresini karşılaştırmanın sonuçlarını göstermektedir. Bu durumda dönüştürme, GPU üzerinde hesaplamalar yapılmadan yalnızca CPU tarafından gerçekleştirildiğinden, işlemci saat frekansının arttırılmasının, dönüşüm süresinin azalmasına (dönüşüm hızının artmasına) yol açtığı açıktır. Dönüşüm hızındaki azalmanın tüm test videoları için yaklaşık olarak aynı olması gerektiği de aynı derecede açıktır. Böylece, video dönüştürücü Xilisoft Video Converter Ultimate 7.7.2 için, işlemci hız aşırtma sırasında birinci, ikinci ve üçüncü video için dönüşüm süresi sırasıyla %9, %11 ve %9 oranında azalır. Wondershare Video Converter Ultimate 6.0.32'de dönüşüm süresi birinci, ikinci ve üçüncü video için sırasıyla %9, %9 ve %10 oranında azalır. Video dönüştürücü Movavi Video Converter 10.2.1 için dönüşüm süresi sırasıyla %13, %12 ve %12 azalır.

Böylece işlemci frekansı %20 oranında hız aşırtıldığında dönüşüm süresi yaklaşık %10 oranında kısalır.

Normal işlemci modunda ve hız aşırtma modunda bir grafik işlemci kullanarak videoları dönüştürme süresini karşılaştıralım (Şekil 10-12).

Video dönüştürücü Xilisoft Video Converter Ultimate 7.7.2 için, işlemci hız aşırtma sırasında birinci, ikinci ve üçüncü video için dönüşüm süresi sırasıyla %10, %10 ve %9 azalır. Wondershare Video Converter Ultimate 6.0.32'de dönüşüm süresi birinci, ikinci ve üçüncü video için sırasıyla %9, %6 ve %5 oranında azalır. Video dönüştürücü Movavi Video Converter 10.2.1 için dönüşüm süresi sırasıyla %0,2, %10 ve %10 azalır.

Gördüğünüz gibi, Xilisoft Video Converter Ultimate 7.7.2 ve Wondershare Video Converter Ultimate 6.0.32 dönüştürücüleri için, işlemciyi hız aşırtma sırasında dönüşüm süresindeki azalma, hem grafik işlemcisi kullanıldığında hem de kullanılmadığında yaklaşık olarak aynıdır; mantıksaldır, çünkü bu dönüştürücüler GPU hesaplamasını çok verimli kullanmazlar. Ancak GPU hesaplamayı etkili bir şekilde kullanan Movavi Video Converter 10.2.1 için, GPU hesaplama modunda işlemciyi hız aşırtmanın dönüştürme süresini azaltma üzerinde çok az etkisi vardır, bu da anlaşılabilir bir durumdur, çünkü bu durumda ana yük grafik işlemcinin üzerine düşer. .

Şimdi çeşitli ekran kartlarıyla yapılan test sonuçlarına bakalım.

Grafik işlemcisinde video kartı ne kadar güçlüyse ve CUDA çekirdeği (veya AMD video kartları için evrensel akış işlemcileri) ne kadar fazlaysa, grafik işlemcisi kullanılırken video dönüştürmenin o kadar etkili olması gerekir. Ancak pratikte işler pek de öyle yürümüyor.

NVIDIA GPU'lara dayalı ekran kartlarında ise durum şu şekildedir. Xilisoft Video Converter Ultimate 7.7.2 ve Wondershare Video Converter Ultimate 6.0.32 dönüştürücüleri kullanırken, dönüştürme süresi pratikte hiçbir şekilde kullanılan video kartının türüne bağlı değildir. Yani, GPU hesaplama modunda NVIDIA GeForce GTX 660Ti, NVIDIA GeForce GTX 460 ve NVIDIA GeForce GTX 280 video kartları için dönüşüm süresi aynıdır (Şekil 13-15).

Pirinç. 1. İlkini dönüştürmenin sonuçları
videoyu normal modda test edin
işlemci işlemi

GPU modunda video kartlarındaki işlemci

Pirinç. 14. İkinci videonun dönüşüm süresinin karşılaştırma sonuçları

Pirinç. 15. Üçüncü videonun dönüşüm süresi karşılaştırmasının sonuçları
GPU modunda çeşitli video kartlarında

Bu yalnızca Xilisoft Video Converter Ultimate 7.7.2 ve Wondershare Video Converter Ultimate 6.0.32 dönüştürücülerinde uygulanan GPU hesaplama algoritmasının etkisiz olması ve tüm grafik çekirdeklerinin aktif kullanımına izin vermemesiyle açıklanabilir. Bu arada, bu dönüştürücüler için GPU kullanma ve kullanmama modlarındaki dönüşüm süresindeki farkın küçük olduğu gerçeğini açıklayan da tam olarak budur.

Movavi Video Converter 10.2.1'de durum biraz farklıdır. Hatırladığımız gibi bu dönüştürücü, GPU hesaplamalarını oldukça verimli bir şekilde kullanabiliyor ve bu nedenle GPU modunda dönüşüm süresi, kullanılan ekran kartının türüne bağlı.

Ancak AMD Radeon HD 6850 ekran kartıyla her şey her zamanki gibi. Ya ekran kartı sürücüsü "çarpıktır" ya da dönüştürücülerde uygulanan algoritmaların ciddi şekilde iyileştirilmesi gerekir, ancak GPU hesaplama kullanıldığında sonuçlar ya iyileşmez ya da daha da kötüleşir.

Daha spesifik olarak durum aşağıdaki gibidir. Xilisoft Video Converter Ultimate 7.7.2 için, ilk test videosunu dönüştürmek için GPU kullanıldığında dönüşüm süresi %43, ikinci videoyu dönüştürürken ise %66 artar.

Üstelik Xilisoft Video Converter Ultimate 7.7.2 aynı zamanda dengesiz sonuçlarla da karakterize ediliyor. Dönüşüm süresindeki değişiklik %40'a ulaşabilir! Bu nedenle tüm testleri on kez tekrarladık ve ortalama sonucu hesapladık.

Ancak Wondershare Video Converter Ultimate 6.0.32 ve Movavi Video Converter 10.2.1 için, üç videoyu dönüştürmek için GPU kullanıldığında dönüşüm süresi hiç değişmiyor! Wondershare Video Converter Ultimate 6.0.32 ve Movavi Video Converter 10.2.1'in dönüştürme sırasında AMD APP teknolojisini kullanmaması veya AMD video sürücüsünün basitçe "çarpık" olması ve bunun sonucunda AMD APP teknolojisinin çalışmaması muhtemeldir. .

Sonuçlar

Testlere dayanarak aşağıdaki önemli sonuçlar çıkarılabilir. Modern video dönüştürücüler aslında daha yüksek dönüştürme hızına olanak tanıyan GPU bilgi işlem teknolojisini kullanabilir. Ancak bu, tüm hesaplamaların tamamen GPU'ya aktarılacağı ve CPU'nun kullanılmadan kalacağı anlamına gelmez. Testlerin gösterdiği gibi, GPGPU teknolojisi kullanıldığında merkezi işlemci meşgul kalır; bu, video dönüştürme için kullanılan sistemlerde güçlü, çok çekirdekli merkezi işlemcilerin kullanımının geçerli olduğu anlamına gelir. Bu kuralın istisnası, AMD GPU'lardaki AMD APP teknolojisidir. Örneğin, AMD APP teknolojisi etkinken Xilisoft Video Converter Ultimate 7.7.2 kullanıldığında, CPU üzerindeki yük gerçekten azalır, ancak bu, dönüşüm süresinin azalmamasına, aksine artmasına neden olur.

Genel olarak, videoyu ek bir grafik işlemci kullanımıyla dönüştürmekten bahsedersek, bu sorunu çözmek için NVIDIA GPU'lu video kartlarının kullanılması tavsiye edilir. Uygulamada görüldüğü gibi, yalnızca bu durumda dönüşüm hızında bir artış elde edilebilir. Üstelik dönüşüm hızındaki gerçek artışın birçok faktöre bağlı olduğunu da unutmamanız gerekiyor. Bunlar giriş ve çıkış video formatları ve elbette video dönüştürücünün kendisidir. Xilisoft Video Converter Ultimate 7.7.2 ve Wondershare Video Converter Ultimate 6.0.32 dönüştürücüleri bu görev için uygun değildir, ancak dönüştürücü ve Movavi Video Converter 10.2.1, NVIDIA GPU'nun yeteneklerini çok etkili bir şekilde kullanabilir.

AMD GPU'lardaki video kartlarına gelince, bunların video dönüştürme görevleri için hiç kullanılmaması gerekir. En iyi durumda, bu, dönüşüm hızında herhangi bir artış sağlamaz ve en kötü durumda, bir düşüş elde edebilirsiniz.

Bugün GPU'ların genel bilgi işlem amaçlı kullanımına ilişkin haberler her köşeden duyulabiliyor. CUDA, Stream ve OpenCL gibi kelimeler sadece iki yıl içinde BT İnternet'te neredeyse en çok alıntı yapılan kelimeler haline geldi. Ancak bu kelimelerin ne anlama geldiğini ve arkasındaki teknolojilerin ne anlama geldiğini herkes bilmiyor. Ve "uçmaya" alışkın olan Linux kullanıcıları için tüm bunlar karanlık bir orman gibi görünüyor.

GPGPU'nun doğuşu

Hepimiz bir bilgisayarın kendisine söylenen herhangi bir kodu çalıştırabilen tek bileşeninin merkezi işlemci olduğunu düşünmeye alışkınız. Uzun bir süre boyunca seri üretilen bilgisayarların neredeyse tamamı, işletim sistemi kodu, tüm yazılımlarımız ve virüslerimiz de dahil olmak üzere akla gelebilecek tüm hesaplamaları gerçekleştiren tek bir işlemciyle donatılmıştı.

Daha sonra, bu tür birkaç bileşenin bulunduğu çok çekirdekli işlemciler ve çok işlemcili sistemler ortaya çıktı. Bu, makinelerin aynı anda birden fazla görevi yerine getirmesine olanak tanıdı ve genel (teorik) sistem performansı, tam olarak makineye kurulu çekirdek sayısı kadar arttı. Ancak çok çekirdekli işlemcileri üretmenin ve tasarlamanın çok zor ve pahalı olduğu ortaya çıktı.

Her çekirdeğin, kendi (oldukça büyük) önbelleği, talimat hattı, SSE blokları, optimizasyonları gerçekleştiren birçok bloğu vb. ile karmaşık ve karmaşık bir x86 mimarisine sahip tam teşekküllü bir işlemciyi barındırması gerekiyordu. vesaire. Bu nedenle, çekirdek sayısını artırma süreci önemli ölçüde yavaşladı ve iki veya dört çekirdeğin açıkça yeterli olmadığı beyaz üniversite önlükleri, videoda bol miktarda bulunan bilimsel hesaplamaları için diğer bilgi işlem gücünü kullanmanın bir yolunu buldu. kart (sonuç olarak, DirectX ve OpenGL işlev çağrılarını kullanarak ek bir işlemciyi taklit eden BrookGPU aracı bile ortaya çıktı).

Merkezi işlemcinin birçok dezavantajından yoksun olan grafik işlemcilerin mükemmel ve çok hızlı bir hesaplama makinesi olduğu ortaya çıktı ve çok geçmeden GPU üreticileri bilimsel zihinlerin gelişmelerine daha yakından bakmaya başladılar (ve aslında nVidia işe alındı) çoğu araştırmacı). Sonuç, karmaşık algoritmaların hesaplanmasının herhangi bir destek olmadan GPU'nun omuzlarına aktarılmasını mümkün kılan bir arayüz tanımlayan nVidia CUDA teknolojisi oldu. Daha sonra onu Close to Metal (şimdi Stream) adı verilen teknolojinin kendi sürümüyle ATi (AMD) takip etti ve çok geçmeden Apple'ın OpenCL adı verilen standart bir sürümü ortaya çıktı.

GPU her şey midir?

Tüm avantajlarına rağmen GPGPU tekniğinin birçok sorunu vardır. Bunlardan ilki uygulama kapsamının çok dar olmasıdır. GPU'lar, artan bilgi işlem gücü ve toplam çekirdek sayısı açısından merkezi işlemcinin çok ilerisine geçmiştir (video kartları, yüzden fazla çekirdekten oluşan bir bilgi işlem birimi taşır), ancak bu kadar yüksek yoğunluk, tasarımın basitleştirilmesinin en üst düzeye çıkarılmasıyla elde edilir. çipin kendisi.

Temelde, GPU'nun ana görevi, girdi olarak çok büyük miktarda öngörülebilir veri almayan basit algoritmalar kullanan matematiksel hesaplamalara iner. Bu nedenle, GPU çekirdekleri çok basit bir tasarıma, yetersiz önbellek boyutlarına ve mütevazı bir talimat setine sahiptir; bu da sonuçta düşük üretim maliyetlerine ve çip üzerine çok yoğun yerleştirme olasılığına neden olur. GPU'lar binlerce çalışanı olan bir Çin fabrikası gibidir. Bazı basit şeyleri oldukça iyi yapıyorlar (ve en önemlisi, hızlı ve ucuz), ancak bir uçağın montajı konusunda onlara güvenirseniz, sonuç en fazla bir yelken kanat olacaktır.

Bu nedenle, GPU'ların ilk sınırlaması hızlı matematiksel hesaplamalara odaklanmalarıdır; bu da GPU'ların uygulama kapsamını multimedya uygulamalarının yanı sıra karmaşık veri işlemeyle ilgili tüm programlara (örneğin arşivleyiciler veya şifreleme sistemleri) yardımcı olacak şekilde sınırlandırır. floresan mikroskobu, moleküler dinamik, elektrostatik ve Linux kullanıcılarının pek ilgisini çekmeyen diğer şeylerle ilgili yazılımlar).

GPGPU ile ilgili ikinci sorun, her algoritmanın GPU üzerinde yürütülmek üzere uyarlanamamasıdır. Bireysel GPU çekirdekleri oldukça yavaştır ve güçleri ancak birlikte çalışırken ortaya çıkar. Bu, programcının onu etkili bir şekilde paralelleştirebildiği kadar algoritmanın da etkili olacağı anlamına gelir. Çoğu durumda, çok az sayıda yazılım geliştiricinin bulunduğu bu tür işleri yalnızca iyi bir matematikçi halledebilir.

Üçüncüsü, GPU'lar grafik kartının kendisine takılı bellekle çalışır, dolayısıyla GPU her kullanıldığında iki ek kopyalama işlemi daha gerçekleşir: uygulamanın RAM'inden veri girişi ve GRAM'den uygulama belleğine veri çıkışı. Tahmin edebileceğiniz gibi bu, uygulamanın çalışma süresindeki herhangi bir faydayı ortadan kaldırabilir (daha sonra ele alacağımız FlacCL aracında olduğu gibi).

Ama hepsi bu değil. OpenCL biçiminde genel kabul görmüş bir standardın varlığına rağmen birçok programcı hâlâ GPGPU tekniğinin satıcıya özel uygulamalarını kullanmayı tercih ediyor. CUDA'nın özellikle popüler olduğu ortaya çıktı; bu, daha esnek bir programlama arayüzü sağlamasına rağmen (bu arada, nVidia sürücülerindeki OpenCL, CUDA'nın üzerine uygulanmıştır), ancak uygulamayı tek bir üreticinin video kartlarına sıkı bir şekilde bağlar.

GPU tarafından hızlandırılan KGPU veya Linux çekirdeği

Utah Üniversitesi'ndeki araştırmacılar, bazı Linux çekirdeği işlevlerinin CUDA çerçevesini kullanan bir GPU üzerinde yürütülmesine olanak tanıyan bir KGPU sistemi geliştirdiler. Bu görevi gerçekleştirmek için, değiştirilmiş bir Linux çekirdeği ve kullanıcı alanında çalışan, çekirdek isteklerini dinleyen ve bunları CUDA kitaplığını kullanarak video kartı sürücüsüne ileten özel bir arka plan programı kullanılır. İlginç bir şekilde, böyle bir mimarinin yarattığı önemli yüke rağmen, KGPU yazarları, eCryptfs dosya sisteminin şifreleme hızını 6 kat artıran AES algoritmasının bir uygulamasını oluşturmayı başardılar.

Şimdi ne var?

Gençliğinden ve yukarıda açıklanan sorunlardan dolayı, GPGPU hiçbir zaman tam anlamıyla yaygın bir teknoloji haline gelmedi, ancak yeteneklerini kullanan kullanışlı yazılımlar (küçük miktarlarda da olsa) mevcuttur. Algoritmalarının paralelleştirilmesi çok kolay olan çeşitli karmaların krakerleri ilk ortaya çıkanlar arasındaydı.

Bir ses parçasını FLAC formatına dönüştürmenize olanak tanıyan FlacCL kodlayıcı gibi multimedya uygulamaları da doğdu. Önceden var olan bazı uygulamalar da GPGPU desteğini aldı; bunlardan en önemlisi, artık çalışmalarının bir kısmını OpenCL kullanarak GPU'ya aktarabilen ImageMagick'tir. Ayrıca veri arşivleyicilerinin ve diğer bilgi sıkıştırma sistemlerinin CUDA/OpenCL'e aktarılmasına yönelik projeler de bulunmaktadır (ATi Unixoid'ler pek sevilmez). Makalenin ilerleyen bölümlerinde bu projelerin en ilginçlerine bakacağız, ancak şimdilik her şeyi başlatmak ve istikrarlı bir şekilde çalışmak için neye ihtiyacımız olduğunu bulmaya çalışalım.

GPU'lar performans açısından x86 işlemcileri çoktan geride bıraktı

· İkinci olarak, video kartının en yeni özel sürücülerinin sisteme yüklenmesi gerekir; bunlar hem karta özgü GPGPU teknolojileri hem de açık OpenCL için destek sağlayacaktır.

· Üçüncüsü, dağıtım geliştiricileri henüz GPGPU destekli uygulama paketlerini dağıtmaya başlamadıklarından, uygulamaları kendimiz oluşturmamız gerekecek ve bunun için üreticilerin resmi SDK'larına ihtiyacımız var: CUDA Toolkit veya ATI Stream SDK. Uygulama oluşturmak için gerekli başlık dosyalarını ve kitaplıkları içerirler.

CUDA Araç Setini yükleyin

Yukarıdaki bağlantıyı takip edin ve Linux için CUDA Araç Kitini indirin (Fedora, RHEL, Ubuntu ve SUSE dağıtım kitleri için çeşitli sürümler arasından seçim yapabilirsiniz; hem x86 hem de x86_64 mimarileri için sürümler vardır). Ek olarak, oradaki geliştiriciler için sürücü kitlerini de indirmeniz gerekiyor (Linux için Geliştirici Sürücüleri, listede ilk sırada yer alıyorlar).

SDK yükleyicisini başlatın:

$ sudo sh cudatoolkit_4.0.17_linux_64_ubuntu10.10.run

Kurulum tamamlandığında sürücülerin kurulumuna geçiyoruz. Bunu yapmak için X sunucusunu kapatın:

# sudo /etc/init.d/gdm stop

Konsolu aç ve sürücü yükleyicisini çalıştırın:

$ sudo sh devdriver_4.0_linux_64_270.41.19.run

Kurulum tamamlandıktan sonra X'i başlatın:

Uygulamaların CUDA/OpenCL ile çalışabilmesi için LD_LIBRARY_PATH değişkeninde CUDA kütüphanelerinin bulunduğu dizinin yolunu ayarladık:

$ ihracat LD_LIBRARY_PATH=/usr/local/cuda/lib64

Veya 32 bit sürümünü yüklediyseniz:

$ ihracat LD_LIBRARY_PATH=/usr/local/cuda/lib32

Derleyicinin bunları uygulama oluşturma aşamasında bulması için CUDA başlık dosyalarının yolunu da belirtmeniz gerekir:

$ ihracat C_INCLUDE_PATH=/usr/local/cuda/include

İşte bu kadar, artık CUDA/OpenCL yazılımı oluşturmaya başlayabilirsiniz.

ATI Stream SDK'yı yükleyin

Stream SDK kurulum gerektirmez; bu nedenle web sitesinden indirdiğiniz AMD arşivini herhangi bir dizine (/opt en iyi seçimdir) paketinden çıkarabilir ve yolunu aynı LD_LIBRARY_PATH değişkenine yazabilirsiniz:

$ wget http://goo.gl/CNCNo

$ sudo tar -xzf ~/AMD-APP-SDK-v2.4-lnx64.tgz -C /opt

$ ihracat LD_LIBRARY_PATH=/opt/AMD-APP-SDK-v2.4-lnx64/lib/x86_64/

$ ihracat C_INCLUDE_PATH=/opt/AMD-APP-SDK-v2.4-lnx64/include/

CUDA Araç Takımında olduğu gibi, 32 bit sistemlerde x86_64'ün x86 ile değiştirilmesi gerekir. Şimdi kök dizine gidin ve icd-registration.tgz arşivini açın (bu bir tür ücretsiz lisans anahtarıdır):

$ sudo tar -xzf /opt/AMD-APP-SDK-v2.4-lnx64/icd-registration.tgz -İLE /

Clinfo aracını kullanarak paketin doğru kurulumunu/çalışmasını kontrol ediyoruz:

$ /opt/AMD-APP-SDK-v2.4-lnx64/bin/x86_64/clinfo

ImageMagick ve OpenCL

OpenCL desteği ImageMagick'te uzun bir süredir mevcuttur, ancak hiçbir dağıtımda varsayılan olarak etkin değildir. Bu nedenle IM'yi kaynaktan kendimiz derlememiz gerekecek. Bunda karmaşık bir şey yok, ihtiyacınız olan her şey zaten SDK'da mevcut, bu nedenle montaj, nVidia veya AMD'den herhangi bir ek kitaplığın kurulmasını gerektirmiyor. Bu nedenle, arşivi kaynaklarla birlikte indirin/paketten çıkarın:

$ wget http://goo.gl/F6VYV

$ tar -xjf ImageMagick-6.7.0-0.tar.bz2

$ cd ImageMagick-6.7.0-0

$ sudo apt-get install build-essential

Yapılandırıcıyı başlatıyoruz ve OpenCL desteği için çıktısını alıyoruz:

$ LDFLAGS=-L$LD_LIBRARY_PATH ./configure | grep -e cl.h -e OpenCL

Komutun doğru çıktısı şöyle görünmelidir:

CL/cl.h kullanılabilirliği kontrol ediliyor... evet

CL/cl.h varlığı kontrol ediliyor... evet

CL/cl.h kontrol ediliyor... evet

OpenCL/cl.h kullanılabilirliği kontrol ediliyor... hayır

OpenCL/cl.h varlığı kontrol ediliyor... hayır

OpenCL/cl.h kontrol ediliyor... hayır

OpenCL kütüphanesi kontrol ediliyor... -lOpenCL

"Evet" kelimesi ya ilk üç satırda ya da ikincisinde (veya her iki seçenekte aynı anda) işaretlenmelidir. Durum böyle değilse, büyük olasılıkla C_INCLUDE_PATH değişkeni doğru şekilde başlatılmamıştır. Son satır "hayır" kelimesiyle işaretlenmişse sorun LD_LIBRARY_PATH değişkenindedir. Her şey yolundaysa derleme/kurulum işlemini başlatın:

$ sudo kurulumu temiz yap

ImageMagick'in gerçekten OpenCL desteğiyle derlenip derlenmediğini kontrol edelim:

$ /usr/local/bin/convert -version | grep Özellikleri

Özellikler: OpenMP OpenCL

Şimdi ortaya çıkan hız kazancını ölçelim. ImageMagick geliştiricileri bunun için evrişim filtresini kullanmanızı önerir:

$ zaman /usr/bin/convert image.jpg -convolve "-1, -1, -1, -1, 9, -1, -1, -1, -1" image2.jpg

$ time /usr/local/bin/convert image.jpg -convolve "-1, -1, -1, -1, 9, -1, -1, -1, -1" image2.jpg

Yeniden boyutlandırma gibi diğer bazı işlemler de artık çok daha hızlı çalışmalıdır, ancak ImageMagick'in grafikleri inanılmaz bir hızla işlemeye başlamasını beklememelisiniz. Şu ana kadar paketin çok küçük bir kısmı OpenCL kullanılarak optimize edildi.

FlacCL (Flacuda)

FlacCL, çalışmalarında OpenCL'in yeteneklerini kullanan, FLAC formatındaki ses dosyalarının kodlayıcısıdır. Windows için CUETools paketine dahildir ancak mono sayesinde Linux'ta da kullanılabilir. Kodlayıcı içeren bir arşiv elde etmek için aşağıdaki komutu çalıştırın:

$ mkdir flaccl && cd flaccl

$ wget www.cuetools.net/install/flaccl03.rar

$ sudo apt-get unrar mono'yu yükle

$ unrar x fl accl03.rar

Programın OpenCL kütüphanesini bulabilmesi için sembolik bir bağlantı oluşturuyoruz:

$ ln -s $LD_LIBRARY_PATH/libOpenCL.so libopencl.so

Şimdi kodlayıcıyı çalıştıralım:

$ mono CUETools.FLACCL.cmd.exe music.wav

Ekranda "Hata: İstenen derleme boyutu gerekli çalışma grubu boyutu olan 32'den büyük" hata mesajı görüntüleniyorsa, sistemimizdeki video kartı çok zayıftır ve ilgili çekirdek sayısı belirtilen sayıya düşürülmelidir. '-- flag group-size XX' seçeneğini kullanarak; burada XX, gerekli çekirdek sayısıdır.

OpenCL'in uzun başlatma süresi nedeniyle, gözle görülür kazanımların yalnızca yeterince uzun parçalarda elde edilebileceğini hemen söyleyeceğim. FlacCL, kısa ses dosyalarını geleneksel sürümüyle neredeyse aynı hızda işler.

oclHashcat veya hızlı bir şekilde kaba kuvvet

Daha önce de söylediğim gibi, çeşitli korsanların ve kaba kuvvet şifre sistemlerinin geliştiricileri, ürünlerine GPGPU desteğini ilk ekleyenler arasındaydı. Onlar için yeni teknoloji gerçek bir kutsal kâse haline geldi ve bu, doğal olarak kolayca paralelleştirilmiş kodun hızlı GPU işlemcilerin omuzlarına kolayca aktarılmasını mümkün kıldı. Dolayısıyla bu tür programların artık onlarca farklı uygulamasının olması şaşırtıcı değil. Ancak bu yazıda bunlardan yalnızca biri hakkında konuşacağım - oclHashcat.

oclHashcat, OpenCL kullanarak GPU'nun gücünü kullanarak, karmalarını son derece yüksek hızda kullanarak şifreleri tahmin edebilen bir bilgisayar korsanıdır. Proje web sitesinde yayınlanan ölçümlere inanıyorsanız, nVidia GTX580'de MD5 şifrelerini seçme hızı saniyede 15.800 milyon kombinasyona kadar çıkmaktadır; bu sayede oclHashcat, ortalama karmaşıklıktaki sekiz karakterlik bir şifreyi yalnızca 9 dakikada bulabilmektedir.

Program OpenCL ve CUDA, MD5, md5($pass.$salt), md5(md5($pass)) ve vBulletin algoritmalarını destekler.< v3.8.5, SHA1, sha1($pass.$salt), хэши MySQL, MD4, NTLM, Domain Cached Credentials, SHA256, поддерживает распределенный подбор паролей с задействованием мощности нескольких машин.

$7z x oclHashcat-0.25.7z

$cd oclHashcat-0.25

Ve programı çalıştırın (örnek bir karma listesi ve örnek bir sözlük kullanacağız):

$ ./oclHashcat64.bin example.hash ?l?l?l?l example.dict

oclHashcat, "EVET" yazarak kabul etmeniz gereken kullanıcı sözleşmesi metnini açacaktır. Bundan sonra, ilerlemesi tuşuna basılarak bulunabilecek arama süreci başlayacaktır. . İşlemi duraklatmak için tıklayın

Devam etmek için - . Doğrudan numaralandırmayı da kullanabilirsiniz (örneğin, aaaaaaaa'dan zzzzzzzz'a):

$ ./oclHashcat64.bin hash.txt ?l?l?l?l ?l?l?l?l

Sözlükte ve doğrudan arama yönteminde çeşitli değişiklikler ve bunların kombinasyonları (bununla ilgili bilgileri docs/examples.txt dosyasında okuyabilirsiniz). Benim durumumda, sözlüğün tamamında arama hızı 11 dakika iken doğrudan arama (aaaaaaa'dan zzzzzzzz'a) yaklaşık 40 dakika sürdü. GPU'nun (RV710 yongası) ortalama hızı 88,3 milyon/s idi.

Sonuçlar

Yazılım geliştirmenin birçok farklı sınırlamasına ve karmaşıklığına rağmen GPGPU, yüksek performanslı masaüstü bilgisayarların geleceğidir. Ama en önemlisi bu teknolojinin yeteneklerini şu anda kullanabiliyor olmanız ve bu sadece Windows makineleri için değil Linux için de geçerli.