Bazı Kavramlar
- CPU: Az sayıda gelişmiş çekirdekleri ihtiva eder
- GPU: Çok sayıda az gelişmiş çekirdekleri ihtiva eder
- CUDA: NVIDIA GPU’ları üzerinde hesaplama yapmamızı sağlayan bir hede
- GPU nedir? Grafik kartıdır.
- GPU ne yapar? Ekrandaki piksellerin rengini hesaplamak için aynı kodu farklı çekirdeklerde milyonlarca kez çalıştırır.
- Peki grafik kartı bilimsel hesaplamalarda ne işe yarayacak?
Pikseli hesaplamak için matematik yapıyoruz. Bilimsel hesaplamalarda da matematik yapıyoruz. O zaman pikseli hesaplamak için kullandığımız donanımı bilimsel hesaplama için de kullanabiliriz. - Neden GPU?
- The NVIDIA GeForce RTX 5060 (Desktop) features a base core clock of 2280 MHz, a boost clock of 2497 MHz, and 3840 CUDA core count.
- Core Ultra 7 270K Plus — Packs 24 cores (8 Performance + 16 Efficiency) hitting boosts up to 5.5 GHz
- Yani çok sayıda basit işlemi yapmak istiyorsak GPU daha avantajlı
- Heterogeneous computing: Farklı tipte hesaplama araclarının aynı anda kullanılması: misal CPU ile GPU
- Host code: CPU tarafında çalışan kod
- Device code: GPU tarafında çalışan kod
Kurulum
- Google’a NVIDIA CUDA Toolkit yazıp çıkan siteden kendi sisteminize uygun olan talimatları uygulayıp kurabilirsiniz.
- Öncesinde driverları güncellemek faydalı olabilir.
- Kurulum sonrası PATH değişkenini eklemek gerekebilir.
- Benim sistem fedora ve eski bir bilgisayar. Yeni cuda sürümünü kuramadığım için eskisini kurmak durumunda kaldım. Biraz zorladı. Yapay zeka bu konuda baya işime yaradı.
Hello CUDA
#include <cstdio>
__global__ void hello()
{
// Device code
printf("Hello from GPU! thread=%d\n", threadIdx.x);
}
int main()
{
// Host code
hello<<<1, 4>>>();
cudaError_t err = cudaDeviceSynchronize();
if (err != cudaSuccess)
{
printf("CUDA error: %s\n", cudaGetErrorString(err));
return 1;
}
return 0;
}
C++- __global__ : GPU üzerinde çalışacak fonksiyonumuz.
- hello <<<1, 4>>>() : asekron fonksiyon çağrısı. Yani GPU’ya sen bu fonksiyonu çalıştır diyip beklemeden devam ediyor.
- cudaDeviceSynchronize() : GPU’nun işini bitirmesini bekle daha devam etme.
- cudaError_t : Error code
- cudaGetErrorString : verilen error code’un açıklama string’ini döndürür.
- threadIdx.x : hangi thread’de olduğumuz.
Şimdi <<< >>> olayına gelelim
fonksiyon_adı<<<grid_dimension, block_dimension>>>(arguments);C++- grid_dimension : Bir grid’de kaç tane block olacağı
- block_dimension : Bir block’da kaç tane thread olabileceği
direk N tane thread çalışsın demek yerine bu şekilde bölerek dağıtıyoruz. Bu biraz donanımsal bir mesele.
Grid
├── Block
│ ├── Thread
│ ├── Thread
│ └── …
├── Block
│ ├── Thread
│ └── …
└── …
burada tek boyutlu dimension kullanıyoruz ama 2-3 boyutlu da yapabiliriz. Misal bir resmi işlerken 26. pixel yerine 27. satırdaki 14. pixel daha kullanışlı
dim3 grid_dim = dim3(1, 1, 1);
dim3 block_dim = dim3(27, 14, 1);
hello<<<grid_dim, block_dim>>>();C++Burada sınırlarımız sonsuz değil. Misal benim makinamda şöyle:
GPU: NVIDIA GeForce GTX 950M
Max threads/block: 1024
Max block dimensions: 1024 x 1024 x 64
Max grid dimensions: 2147483647 x 65535 x 65535
Bunları sorgulamak için şu kodu kullanıyoruz:
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, 0);
printf("GPU: %s\n", prop.name);
printf("Max threads/block: %d\n", prop.maxThreadsPerBlock);
printf("Max block dimensions: %d x %d x %d\n",
prop.maxThreadsDim[0],
prop.maxThreadsDim[1],
prop.maxThreadsDim[2]);
printf("Max grid dimensions: %d x %d x %d\n",
prop.maxGridSize[0],
prop.maxGridSize[1],
prop.maxGridSize[2]);C++
Leave a Reply