Bildiğim kadarıyla GPU'lar, CPU'lardan bazen daha hızlı oluyor. Bu da Gentoo falan derlemeyi bayağı hızlandırır. Peki neden bunu akıl etmiyorlar?
Detaylar
Kim cevapladı?The Shorekeeper
Üstün
GPU, CPU gibi çalışmıyor çünkü. Bunu ben de düşünmüştüm.
Kısaca sebep, iki donanım arasındaki mimari farklar. Bu yüzden derleyemiyoruz.
GPU'lar grafik işlemleri için dizayn edilmiş parçalar. Vektör hesaplama, matris işlemleri vs.
Kısaca sebep, iki donanım arasındaki mimari farklar. Bu yüzden derleyemiyoruz.
GPU'lar grafik işlemleri için dizayn edilmiş parçalar. Vektör hesaplama, matris işlemleri vs.
- Katılım
- 22 Aralık 2023
- Mesajlar
- 4.733
- Makaleler
- 4
- Çözümler
- 90
- Beğeniler
- 6.810
Ekran kartları kayar nokta(özellikle 32 bit) ve tam sayıda yüksek hızlı toplama ve çarpma işlemi yapmak için optimize edilmiştir, işlemci kadar versatil değildir.
En önemli şey ise mantık. Derleme süreci iç içe karmaşık mantık içerir. Derleyici belki binlerce karşılaştırma yapar ve optimizasyon için karmaşık maliyet model analizleri yapabilir.
İşlemci hem versatil yani birden fazla veri tipini işleyebilir ve sayılar arasında kompleks matematik yürütebilir. Aynı zamanda kompleks mantık işlemlerini de yapabilir. Mantıktan kasıt matematiksel mantık; ve/veya/ya da gibi.
En önemli şey ise mantık. Derleme süreci iç içe karmaşık mantık içerir. Derleyici belki binlerce karşılaştırma yapar ve optimizasyon için karmaşık maliyet model analizleri yapabilir.
İşlemci hem versatil yani birden fazla veri tipini işleyebilir ve sayılar arasında kompleks matematik yürütebilir. Aynı zamanda kompleks mantık işlemlerini de yapabilir. Mantıktan kasıt matematiksel mantık; ve/veya/ya da gibi.
Jennifer
Üstün
Baştan Uyarayım: Baya bir uzun yazı olacak. Eğer compiler'ın nasıl çalıştığını merak etmiyorsanız geçin. Anlatımı C dili üzerinden yapacağım.
Derleyiciler, yazdığınız yüksek seviyeli kodu doğrudan makine diline çeviremez. Bunun yerine, birçok aşamadan geçirerek işler.
İşte tam da bu yazıda bu aşamaları açıklayacağım:
"Ben elma yedim."
→ Ben (zamir), elma (isim), yedim (fiil), . (noktalama)
Eğer yazım hatası varsa burada hata verir.
Gerçek hayattan örnek:
"Ben elma yedim." doğrudur ama "Yedim elma ben." bozuk bir cümledir, hata verir.
kod.c
Gerçek hayattan örnek:
"Ben televizyonu kustum." cümlesinde gramer doğru olabilir ama mantık hatası içerir, yani hatalı.
Örneğin:
LLVM IR üzerinde aynı koda dönüşür:
Gerçek hayattan örnek:
Diyelim ki elinizde Türkçe, İspanyolca ve Almanca bir cümle var, derleyici bunlarla ayrı ayrı uğraşmak yerine hepsini İngilizce diline çevirip oradan devam ediyor, böylelikle daha rahat iş yapabiliyor.
Kayan sayılarla ilgili çok daha ilginç bir örnek vereyim:
Makine dilinde kayan noktalı sayılar (floating point) tamsayılar gibi doğrudan aritmetik birimlerde (ALU) işlenemez. Bu işlemler özel olarak tasarlanmış FPU (Floating Point Unit) birimlerinde gerçekleştirilir. Ancak bu x86 üzerinde ana FPU (x87) yaklaşık 45 yıllık bir mimari temele dayandığı için berbat çalışır.
Günümüzde matris çarpımı gibi vektör-tabanlı işlemler için SIMD (Single Instruction, Multiple Data) tabanlı genişletmeler (örneğin SSE, AVX) kullanılır. Derleyiciler, derleme sırasında verdiğimiz optimizasyon bayraklarına göre bu işlemleri klasik FPU yerine SIMD registerları ile optimize edebilir.
Aşağıda aynı floating point işlemini hem klasik x87 FPU hem de AVX komut seti kullanarak derleyip elde ettiğimiz Assembly çıktısını karşılaştıracağız.
X87:
Kodu anlamanıza gerek yok, sadece ne kadar uzun olduğuna bakın. İşlemciler uzun talimatlarda daha düşük performansla çalışır ve daha yüksek güç tüketir. Aynısını AVX ile yapalım:
GPU’lar neden derleyici gibi davranamaz?
Bir GPU’nun bu 6 aşamayı CPU kadar verimli yapamamasının sebebi mimarisinin ve komut setinin farklı olmasıdır.
Derleyiciyi CPU'da kullanmak mantıklı bir iştir çünkü analiz, karar verme, hata denetimi gibi çok adımlı, sıralı mantıksal işlemleri yapabilir (GPU'da her bir karmaşık adımın bütün threadlarda yapıldığını hayal edin, kaos çıkar).
GPU ise bu iş için fazla hantal, fazla paralel, fazla "aynı anda aynı şeyi yap" mantığına sahiptir. Bu yüzden derleyicileri GPU üzerinde kullanırsanız tam da bu hissiyata kapılırsınız:
Şaka bir yana, CPU'lar 10 parmakla 10 marifet görürken GPU'lar 10 parmakla 1 marifet görüyor, ama CPU'dan milyon kez daha iyi yapıyor o marifeti.
Makale tarzında oldu biraz ama idare edin, umarım beğenirsiniz
Derleyiciler, yazdığınız yüksek seviyeli kodu doğrudan makine diline çeviremez. Bunun yerine, birçok aşamadan geçirerek işler.
İşte tam da bu yazıda bu aşamaları açıklayacağım:
1. Lexical Analysis (Sözcüksel Analiz):
Derleyici, insan gibi yazdığınızfloat mrb = 12.0f; gibi bir satırı doğrudan anlayamaz. Önce bu satırı parçalara ayırarak tokenize etmesi gerekir, bunu da bu şekilde yapar:- float → anahtar kelime (veri türü)
- mrb → değişken ismi
- = → atama operatörü
- 12.0f → sayı
- ; → noktalama
"Ben elma yedim."
→ Ben (zamir), elma (isim), yedim (fiil), . (noktalama)
2. Syntax Analysis (Sözdizimsel Analiz):
Token'ler sıralama olmadan bir araya gelirse hiçbir şey oluşturmaz, derleyici, bir ağaç yapısı (parse tree) oluşturarak bunu kontrol eder:
C:
=
/ \
float mrb
\
12.0f
Eğer yazım hatası varsa burada hata verir.
Gerçek hayattan örnek:
"Ben elma yedim." doğrudur ama "Yedim elma ben." bozuk bir cümledir, hata verir.
3. Semantic Analysis (Anlamsal Analiz):
Bu aşamada, sözdizimi doğru bile olsa, anlam hataları tespit edilir. Örnek:kod.c
C:
#include <stdio.h>
void Fonksiyonum();
int main()
{
int test = 20.2f; // Hatalı, integer'a float değerinde bir sayı veremezsiniz çünkü tamsayı bekler, ya hata alırsınız ya da uyarı alıp kayıplı bir dönüştürme yapmak zorunda kalırsınız.
float test = 212.0f; // Hatalı, "test" isimli değişken zaten yukarıda tanımlanmış.
int mrb = mrb2; // Hatalı, mrb2 diye bir değişken yok.
Fonksiyonum(); // Doğru, Fonksiyonun adresini tespit etmek derleyicinin işi değil bağlayıcının işi, eğer sorun varsa bağlayıcı hata verir.
Fonksiyonum2(); // Hatalı, Fonksiyonum2() hiçbir yerde tanımlanmamış.
return 0;
}
Gerçek hayattan örnek:
"Ben televizyonu kustum." cümlesinde gramer doğru olabilir ama mantık hatası içerir, yani hatalı.
4. Intermediate Code Generation (Ara Kod Oluşturma):
Makine koduna geçmeden önce, derleyici kodu bir ara dile (örneğin LLVM IR) çevirir. Bu sayede platformdan bağımsız çalışabilir ve bir sonraki aşamaları daha verimli yapabilir.Örneğin:
Kod:
// C kodu
int topla(int a, int b) { return a + b; }
Kod:
// Rust kodu
pub fn topla(a: i32, b: i32) -> i32 { a + b }
LLVM IR üzerinde aynı koda dönüşür:
Kod:
// LLVM-IR Kodu (LLVM-IR'de yorum yok aslında, ama aramızda kalsın :P)
define i32 @topla(i32 %a, i32 %b) {
%result = add i32 %a, %b
ret i32 %result
}
Gerçek hayattan örnek:
Diyelim ki elinizde Türkçe, İspanyolca ve Almanca bir cümle var, derleyici bunlarla ayrı ayrı uğraşmak yerine hepsini İngilizce diline çevirip oradan devam ediyor, böylelikle daha rahat iş yapabiliyor.
5. Optimizasyon:
Derleyici, kodunuzu daha verimli çalışması için optimize eder. Örneğin:
C:
int a = 44 + 38; // Derleyici bunu doğrudan int a = 82; yapar, böylelikle işlemsiz olur ve kod hızlanır.
C:
void add4(float *a, float *b, float *result)
{
for (int i = 0; i < 4; i++) {
result[i] = a[i] + b[i];
}
}
Günümüzde matris çarpımı gibi vektör-tabanlı işlemler için SIMD (Single Instruction, Multiple Data) tabanlı genişletmeler (örneğin SSE, AVX) kullanılır. Derleyiciler, derleme sırasında verdiğimiz optimizasyon bayraklarına göre bu işlemleri klasik FPU yerine SIMD registerları ile optimize edebilir.
Aşağıda aynı floating point işlemini hem klasik x87 FPU hem de AVX komut seti kullanarak derleyip elde ettiğimiz Assembly çıktısını karşılaştıracağız.
X87:
Kod:
add4: ; Fonksiyon girişi
pushl %ebp ; ebp'yi (base pointer) stack'e kaydeder
movl %esp, %ebp ; ebp'yi şu anki esp (stack pointer) değerine ayarlar, fonksiyon içi stack frame oluşturur
subl $16, %esp ; lokal değişkenler için yer ayır (4 * 4)
movl $0, -4(%ebp) ; döngüyü başlatan i değişkenini 4 bytelık bir şekilde 0 sayısına ayarla (int 4 byte'dır)
.L2: ; döngü başlangıcı
movl -4(%ebp), %eax ; eax = i
leal 0(,%eax,4), %edx ; edx = i * 4 (float 4 byte'dır)
movl 8(%ebp), %eax ; eax = a (ilk argümanın adresi float* a)
addl %edx, %eax ; eax = a + i*4 (c dilinde a[i] tarafına karşılık veriyoruz)
flds (%eax) ; st(0) = a[i] (x87 FPU stackine yükle)
movl -4(%ebp), %eax ; eax = i
leal 0(,%eax,4), %edx ; edx = i * 4
movl 12(%ebp), %eax ; eax = b (ikinci argümanın adresi float* b)
addl %edx, %eax ; eax = b + i*4 (b[i]'nin adresi)
flds (%eax) ; st(0) = b[i], st(1) = a[i]
faddp %st, %st(1) ; st(1) = a[i] + b[i], sonra st(0) pop edilir
; faddp: FPU stackinin en üstündeki iki değeri toplar (st(0) + st(1))
; sonucu st(1)'e kaydeder ve st(0)'ı stack'ten çıkarır (pop)
movl -4(%ebp), %eax ; eax = i
leal 0(,%eax,4), %edx ; edx = i * 4
movl 16(%ebp), %eax ; eax = result (üçüncü argümanın adresi float* result)
addl %edx, %eax ; eax = result + i*4 (result[i]'nin adresi)
fstps (%eax) ; result[i] = st(0); sonra st(0) pop edilir
addl $1, -4(%ebp) ; i++
cmpl $3, -4(%ebp) ; karşılaştırma, i 3 veya altında mı kontrol eder
jle .L2 ; eğer öyleyse döngü tekrardan devam eder
leave ; üstteki stackler temizlenir
ret ; fonksiyon döndürülür
Kodu anlamanıza gerek yok, sadece ne kadar uzun olduğuna bakın. İşlemciler uzun talimatlarda daha düşük performansla çalışır ve daha yüksek güç tüketir. Aynısını AVX ile yapalım:
Kod:
add4:
vmovups xmm0, XMMWORD PTR [rdi] ; a[0..3] -> xmm0
vmovups xmm1, XMMWORD PTR [rsi] ; b[0..3] -> xmm1
vaddps xmm0, xmm0, xmm1 ; xmm0 = a[0]+b[0], a[1]+b[1], a[2]+b[2], a[3]+b[3] (element-wise)
vmovups XMMWORD PTR [rdx], xmm0 ; result = xmm0 (ama unaligned)
ret ; fonkisyon döndürür
xmm registerları 4 adresi aynı anda işleyebilir, resmen GPU gibi çalışır ve bu yapılara SIMD (Tek talimat, çoklu veri) deriz.6. Code Generation (Kod Üretimi)
Son aşamada ara kod platforma özgü Assembly'ye çevrilir ve çalıştırılmaya hazır hale gelir.Peki bunları neden anlattım?
Şu sorunun cevabı için:GPU’lar neden derleyici gibi davranamaz?
Bir GPU’nun bu 6 aşamayı CPU kadar verimli yapamamasının sebebi mimarisinin ve komut setinin farklı olmasıdır.
Amaç?
CPU:- Genel amaçlıdır (ALU, branch prediction, cache'ler ile optimize).
- Sıralı ve mantıksal işlemlerde mükemmel.
- Talimat başına düşük gecikme, yüksek esneklik (çok fazla şey yapabiliyor).
- Paralel işleme uygundur (kriptografi, yapay zeka, blockchain ve rendering gibi yerlerde mükemmel).
- SIMD yapısı vardır (aynı işlemi çok veri üzerinde uygular).
- Dallanma, sıralı karar alma, token analizi gibi işlerde verimsiz.
Derleyiciyi CPU'da kullanmak mantıklı bir iştir çünkü analiz, karar verme, hata denetimi gibi çok adımlı, sıralı mantıksal işlemleri yapabilir (GPU'da her bir karmaşık adımın bütün threadlarda yapıldığını hayal edin, kaos çıkar).
GPU ise bu iş için fazla hantal, fazla paralel, fazla "aynı anda aynı şeyi yap" mantığına sahiptir. Bu yüzden derleyicileri GPU üzerinde kullanırsanız tam da bu hissiyata kapılırsınız:
Şaka bir yana, CPU'lar 10 parmakla 10 marifet görürken GPU'lar 10 parmakla 1 marifet görüyor, ama CPU'dan milyon kez daha iyi yapıyor o marifeti.
Makale tarzında oldu biraz ama idare edin, umarım beğenirsiniz
Structnix
Uzman
- Katılım
- 3 Nisan 2025
- Mesajlar
- 29
- Beğeniler
- 20
Gayet güzel bir açıklama olmuş, elinize sağlık.Baştan Uyarayım: Baya bir uzun yazı olacak. Eğer compiler'ın nasıl çalıştığını merak etmiyorsanız geçin. Anlatımı C dili üzerinden yapacağım.
Derleyiciler, yazdığınız yüksek seviyeli kodu doğrudan makine diline çeviremez. Bunun yerine, birçok aşamadan geçirerek işler.
Eki Görüntüle 139370
İşte tam da bu yazıda bu aşamaları açıklayacağım:
1. Lexical Analysis (Sözcüksel Analiz):
Derleyici, insan gibi yazdığınızfloat mrb = 12.0f;gibi bir satırı doğrudan anlayamaz. Önce bu satırı parçalara ayırarak tokenize etmesi gerekir, bunu da bu şekilde yapar:
Gerçek hayattan örnek:
- float → anahtar kelime (veri türü)
- mrb → değişken ismi
- = → atama operatörü
- 12.0f → sayı
- ; → noktalama
"Ben elma yedim."
→ Ben (zamir), elma (isim), yedim (fiil), . (noktalama)
2. Syntax Analysis (Sözdizimsel Analiz):
Token'ler sıralama olmadan bir araya gelirse hiçbir şey oluşturmaz, derleyici, bir ağaç yapısı (parse tree) oluşturarak bunu kontrol eder:
C:= / \ float mrb \ 12.0f
Eğer yazım hatası varsa burada hata verir.
Gerçek hayattan örnek:
"Ben elma yedim." doğrudur ama "Yedim elma ben." bozuk bir cümledir, hata verir.
3. Semantic Analysis (Anlamsal Analiz):
Bu aşamada, sözdizimi doğru bile olsa, anlam hataları tespit edilir. Örnek:
kod.c
C:#include <stdio.h> void Fonksiyonum(); int main() { int test = 20.2f; // Hatalı, integer'a float değerinde bir sayı veremezsiniz çünkü tamsayı bekler, ya hata alırsınız ya da uyarı alıp kayıplı bir dönüştürme yapmak zorunda kalırsınız. float test = 212.0f; // Hatalı, "test" isimli değişken zaten yukarıda tanımlanmış. int mrb = mrb2; // Hatalı, mrb2 diye bir değişken yok. Fonksiyonum(); // Doğru, Fonksiyonun adresini tespit etmek derleyicinin işi değil bağlayıcının işi, eğer sorun varsa bağlayıcı hata verir. Fonksiyonum2(); // Hatalı, Fonksiyonum2() hiçbir yerde tanımlanmamış. return 0; }
Gerçek hayattan örnek:
"Ben televizyonu kustum." cümlesinde gramer doğru olabilir ama mantık hatası içerir, yani hatalı.
4. Intermediate Code Generation (Ara Kod Oluşturma):
Makine koduna geçmeden önce, derleyici kodu bir ara dile (örneğin LLVM IR) çevirir. Bu sayede platformdan bağımsız çalışabilir ve bir sonraki aşamaları daha verimli yapabilir.
Örneğin:
Kod:// C kodu int topla(int a, int b) { return a + b; }Kod:// Rust kodu pub fn topla(a: i32, b: i32) -> i32 { a + b }
LLVM IR üzerinde aynı koda dönüşür:
Kod:// LLVM-IR Kodu (LLVM-IR'de yorum yok aslında, ama aramızda kalsın :P) define i32 @topla(i32 %a, i32 %b) { %result = add i32 %a, %b ret i32 %result }
Gerçek hayattan örnek:
Diyelim ki elinizde Türkçe, İspanyolca ve Almanca bir cümle var, derleyici bunlarla ayrı ayrı uğraşmak yerine hepsini İngilizce diline çevirip oradan devam ediyor, böylelikle daha rahat iş yapabiliyor.
5. Optimizasyon:
Derleyici, kodunuzu daha verimli çalışması için optimize eder. Örneğin:
Kayan sayılarla ilgili çok daha ilginç bir örnek vereyim:C:int a = 44 + 38; // Derleyici bunu doğrudan int a = 82; yapar, böylelikle işlemsiz olur ve kod hızlanır.
Makine dilinde kayan noktalı sayılar (floating point) tamsayılar gibi doğrudan aritmetik birimlerde (ALU) işlenemez. Bu işlemler özel olarak tasarlanmış FPU (Floating Point Unit) birimlerinde gerçekleştirilir. Ancak bu x86 üzerinde ana FPU (x87) yaklaşık 45 yıllık bir mimari temele dayandığı için berbat çalışır.C:void add4(float *a, float *b, float *result) { for (int i = 0; i < 4; i++) { result[i] = a[i] + b[i]; } }
Günümüzde matris çarpımı gibi vektör-tabanlı işlemler için SIMD (Single Instruction, Multiple Data) tabanlı genişletmeler (örneğin SSE, AVX) kullanılır. Derleyiciler, derleme sırasında verdiğimiz optimizasyon bayraklarına göre bu işlemleri klasik FPU yerine SIMD registerları ile optimize edebilir.
Aşağıda aynı floating point işlemini hem klasik x87 FPU hem de AVX komut seti kullanarak derleyip elde ettiğimiz Assembly çıktısını karşılaştıracağız.
X87:
Kod:add4: ; Fonksiyon girişi pushl %ebp ; ebp'yi (base pointer) stack'e kaydeder movl %esp, %ebp ; ebp'yi şu anki esp (stack pointer) değerine ayarlar, fonksiyon içi stack frame oluşturur subl $16, %esp ; lokal değişkenler için yer ayır (4 * 4) movl $0, -4(%ebp) ; döngüyü başlatan i değişkenini 4 bytelık bir şekilde 0 sayısına ayarla (int 4 byte'dır) .L2: ; döngü başlangıcı movl -4(%ebp), %eax ; eax = i leal 0(,%eax,4), %edx ; edx = i * 4 (float 4 byte'dır) movl 8(%ebp), %eax ; eax = a (ilk argümanın adresi float* a) addl %edx, %eax ; eax = a + i*4 (c dilinde a[i] tarafına karşılık veriyoruz) flds (%eax) ; st(0) = a[i] (x87 FPU stackine yükle) movl -4(%ebp), %eax ; eax = i leal 0(,%eax,4), %edx ; edx = i * 4 movl 12(%ebp), %eax ; eax = b (ikinci argümanın adresi float* b) addl %edx, %eax ; eax = b + i*4 (b[i]'nin adresi) flds (%eax) ; st(0) = b[i], st(1) = a[i] faddp %st, %st(1) ; st(1) = a[i] + b[i], sonra st(0) pop edilir ; faddp: FPU stackinin en üstündeki iki değeri toplar (st(0) + st(1)) ; sonucu st(1)'e kaydeder ve st(0)'ı stack'ten çıkarır (pop) movl -4(%ebp), %eax ; eax = i leal 0(,%eax,4), %edx ; edx = i * 4 movl 16(%ebp), %eax ; eax = result (üçüncü argümanın adresi float* result) addl %edx, %eax ; eax = result + i*4 (result[i]'nin adresi) fstps (%eax) ; result[i] = st(0); sonra st(0) pop edilir addl $1, -4(%ebp) ; i++ cmpl $3, -4(%ebp) ; karşılaştırma, i 3 veya altında mı kontrol eder jle .L2 ; eğer öyleyse döngü tekrardan devam eder leave ; üstteki stackler temizlenir ret ; fonksiyon döndürülür
Kodu anlamanıza gerek yok, sadece ne kadar uzun olduğuna bakın. İşlemciler uzun talimatlarda daha düşük performansla çalışır ve daha yüksek güç tüketir. Aynısını AVX ile yapalım:
Kod:add4: vmovups xmm0, XMMWORD PTR [rdi] ; a[0..3] -> xmm0 vmovups xmm1, XMMWORD PTR [rsi] ; b[0..3] -> xmm1 vaddps xmm0, xmm0, xmm1 ; xmm0 = a[0]+b[0], a[1]+b[1], a[2]+b[2], a[3]+b[3] (element-wise) vmovups XMMWORD PTR [rdx], xmm0 ; result = xmm0 (ama unaligned) ret ; fonkisyon döndürürxmmregisterları 4 adresi aynı anda işleyebilir, resmen GPU gibi çalışır ve bu yapılara SIMD (Tek talimat, çoklu veri) deriz.
6. Code Generation (Kod Üretimi)
Son aşamada ara kod platforma özgü Assembly'ye çevrilir ve çalıştırılmaya hazır hale gelir.
Eki Görüntüle 139372
Peki bunları neden anlattım?
Şu sorunun cevabı için:
GPU’lar neden derleyici gibi davranamaz?
Bir GPU’nun bu 6 aşamayı CPU kadar verimli yapamamasının sebebi mimarisinin ve komut setinin farklı olmasıdır.
Amaç?
CPU:
GPU:
- Genel amaçlıdır (ALU, branch prediction, cache'ler ile optimize).
- Sıralı ve mantıksal işlemlerde mükemmel.
- Talimat başına düşük gecikme, yüksek esneklik (çok fazla şey yapabiliyor).
- Paralel işleme uygundur (kriptografi, yapay zeka, blockchain ve rendering gibi yerlerde mükemmel).
- SIMD yapısı vardır (aynı işlemi çok veri üzerinde uygular).
- Dallanma, sıralı karar alma, token analizi gibi işlerde verimsiz.
Derleyiciyi CPU'da kullanmak mantıklı bir iştir çünkü analiz, karar verme, hata denetimi gibi çok adımlı, sıralı mantıksal işlemleri yapabilir (GPU'da her bir karmaşık adımın bütün threadlarda yapıldığını hayal edin, kaos çıkar).
GPU ise bu iş için fazla hantal, fazla paralel, fazla "aynı anda aynı şeyi yap" mantığına sahiptir. Bu yüzden derleyicileri GPU üzerinde kullanırsanız tam da bu hissiyata kapılırsınız:
Eki Görüntüle 139369
Şaka bir yana, CPU'lar 10 parmakla 10 marifet görürken GPU'lar 10 parmakla 1 marifet görüyor, ama CPU'dan milyon kez daha iyi yapıyor o marifeti.
Makale tarzında oldu biraz ama idare edin, umarım beğenirsiniz![]()
CPU komutlarını, GPU komutuna çeviren bir yazılım çıkarsa olur. Bir nevi CPU emülasyonu yapılmalı yani. Şu an olmaz. Çünkü CPU komutları ve mimarisi ile GPU komutları ve mimarisi farklı şeydir. C/C++, CPU odaklı derleme yapar.
Derlenen yazılımı da CPU anlar ve işler.
Derlenen yazılımı da CPU anlar ve işler.
Yukaridaki arkadaslar cok guzel anlatmis ama bir iki kelam etmezsem icimde kalacak. GPU ile CPU arasindaki veri aktarim hizi da bu konunun gercege gecirilmemesi konusunda bir etkendir. PCIe koprusu hayli hizli olmasina ragmen buyuk dosya transferleri icin CPU'ya asla bir alternatif olamaz.
Bu yuzden grafik programlama yaparken gereken matrisler GPU'ya yollanir ve gereken "linear transformation" islemlerini ekran karti yapar. Is burada matematige ve ekran kartinin lineer cebir yapmaya ozel olarak tasarlanmis bir donanim olmasina dayaniyor tabii ki; shader'larin arkasindaki kodlari incelerseniz zaten 4x4 matrislerde genelde sinus ve kosinus degerleri ile islemlerin yapilarak ona gore piksellerin boyandigini goreceksiniz.
Genel amacli islemler yapmak icin daha yeni nesil GPU'larda CUDA ya da GPGPU cekirdekleri goruyoruz. Bunlar genelde islemcinin yukunu almak ve genel matematiksel/algoritmik hesaplar yapmak (finans uygulamalari, parcacik simulasyonlari, fizik simulasyonlari) icin kullaniliyor.
Bir cross-compiler belki bu yontemle calisabilir ama tekrar veri okumak icin PCIe koprusunun azizligine takiliyor; diger uygulamalarda kod ve icindeki veri yine bir nevi GPU'ya bagli oluyor (parcacik simulasyonlarindaki parcaciklari zaten yazilan kod uretiyor belli sabit ozelliklere gore, kripto para madenciligi uygulamalarinda zaten belli bir algoritmaya gore anahtar cozuluyor vs.) fakat derleme isi icin yine diskten veriyi bellege okuyup yorumlayip degerlendirmek gerekiyor, burada da islemci zaten GPU'dan cok daha ustun oluyor.
Ek olarak, meraklilar su videoya goz atabilir:
Bu yuzden grafik programlama yaparken gereken matrisler GPU'ya yollanir ve gereken "linear transformation" islemlerini ekran karti yapar. Is burada matematige ve ekran kartinin lineer cebir yapmaya ozel olarak tasarlanmis bir donanim olmasina dayaniyor tabii ki; shader'larin arkasindaki kodlari incelerseniz zaten 4x4 matrislerde genelde sinus ve kosinus degerleri ile islemlerin yapilarak ona gore piksellerin boyandigini goreceksiniz.
Genel amacli islemler yapmak icin daha yeni nesil GPU'larda CUDA ya da GPGPU cekirdekleri goruyoruz. Bunlar genelde islemcinin yukunu almak ve genel matematiksel/algoritmik hesaplar yapmak (finans uygulamalari, parcacik simulasyonlari, fizik simulasyonlari) icin kullaniliyor.
Bir cross-compiler belki bu yontemle calisabilir ama tekrar veri okumak icin PCIe koprusunun azizligine takiliyor; diger uygulamalarda kod ve icindeki veri yine bir nevi GPU'ya bagli oluyor (parcacik simulasyonlarindaki parcaciklari zaten yazilan kod uretiyor belli sabit ozelliklere gore, kripto para madenciligi uygulamalarinda zaten belli bir algoritmaya gore anahtar cozuluyor vs.) fakat derleme isi icin yine diskten veriyi bellege okuyup yorumlayip degerlendirmek gerekiyor, burada da islemci zaten GPU'dan cok daha ustun oluyor.
Ek olarak, meraklilar su videoya goz atabilir:
Yeni konular
-
-
-
-
-
-
Elektronik Seçili Lenovo laptoplarda %5 indirim kampanyası
- Fırsat Ekibi
- Mesaj: 0
-
-
Batman'da bir çocuğun yaktığı karton, arabayı tutuşturdu
- Michael MYERS
- Mesaj: 5
-