- Veri akışı genelde CPU <-> RAM arasında olur.
- GPU’nun ise kendine ait RAM’i vardır ve biz buna dümdüz erişemiyoruz.
- Şöyle bir akış var:
- CPU’da işlenecek data’yı oluştur -> host data -> h_data
- h_data’nın boyutu kadar GPU’da memory allocate et-> device data -> d_data
- CPU’daki datayı GPU’ya kopyala => h_data->d_data
- Kernel’ı çalıştır ve d_data’yı manipüle et
- GPU’daki datayı CPU’ya kopyala => d_data->h_data
- GPU’daki belleği free et
- İşlenmiş h_data’yı kullan
#include <cstdio>
#include <iostream>
#include <vector>
__global__ void hello(int* i)
{
int xID = blockDim.x * blockIdx.x + threadIdx.x;
i[xID] *= 2;
}
int main()
{
// datamızın sayısı ve byte cinsinden boyutu
int dataSize = 16;
int byteSize = dataSize * sizeof(int);
// CPU tarafından memory initialize ettik
std::vector<int> h_data(dataSize);
for(int i = 0; i < h_data.size(); i++)
h_data[i] = i;
// GPU tarafından memory allocate ettik
int* d_data = nullptr;
cudaMalloc(&d_data, byteSize);
// CPU --data--> GPU
cudaMemcpy(
d_data,
h_data.data(),
byteSize,
cudaMemcpyHostToDevice
);
// kernel'ı çalıştırdık
hello<<<1, dataSize>>>(d_data);
cudaError_t err = cudaDeviceSynchronize();
if (err != cudaSuccess)
{
printf("CUDA error: %s\n", cudaGetErrorString(err));
return 1;
}
// GPU --data--> CPU
cudaMemcpy(
h_data.data(),
d_data,
byteSize,
cudaMemcpyDeviceToHost
);
// Free GPU memory
cudaFree(d_data);
// print values to console
for(const int& i : h_data)
std::cout << i << ", ";
std::cout << std::endl;
return 0;
}
// ÇIKTI:
// 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
C++- dataSize: Kaç tane int var
- byteSize: Bu kadar int kaç byte eder
- h_data: Host data. Vector olarak tanımladık ama direk pointer yapıp malloc /new gibi şeylerle bu kısmını halledebilirdik.
- d_data : GPU’daki datanın pointer’ı
- cudaMalloc(&d_data, byteSize) : GPU’da memory allocate eden fonksiyon
- &d_data : d_data’nın adresini veriyoruz. Böylece fonksiyon pointer’ın değerini değiştirebilir.
- byteSize : data’nın byte cinsinden boyutu
- cudaMemcpy() : Bellek kopyalama yapan fonksiyon.
- cudaMemcpyHostToDevice : CPU->GPU
- cudaMemcpyDeviceToHost : GPU->CPU
- cudaMemcpyDeviceToDevice : GPU->GPU
- cudaFree() : GPU belleğini serbest bırakır.
Bazen tek başına bir array atmak yeterli olmaz yanında size da göndermemiz gerekir:
__global__ void hello(int* i, int size)
{
int xID = blockDim.x * blockIdx.x + threadIdx.x;
if(xID<size)
i[xID] *= 2;
}
int main()
{
// ...
int mySize = 12;
hello<<<1, dataSize>>>(d_data, mySize);
// ...
}C++
Leave a Reply