GPUプログラミング

GPU プログラミングでは、CPU ハードウェアと GPU ハードウェアの両方を考慮する必要があります。この種のプログラミングは異種混合プログラミングと呼ばれます。

コードは CPU 上で実行を開始し、大量の並列化が必要な部分に遭遇し、それを GPU 上で並列化し、他の計算のために結果を CPU に返します。

CPU上でのベクトル加算

  • メモリ空間を解放し、
  • 2 つのベクトルを初期化します。
  • 加算をループするか、ベクトル化された加算を使用する
  • 空きメモリ

この計算効率は帯域幅によって非常に制限されるため、たとえば、次のコードでは長さ 100 万の 2 つのベクトルの加算を計算する必要があります。

#include <iostream>
int main(void) {
    
    
int N = 1<<20; // 1M elements
float *x = new float[N]; // Allocate memory
float *y = new float[N];
// initialize x and y on the CPU
for (int i = 0; i < N; i++) {
    
    
 x[i] = 1.0f; y[i] = 2.0f;
}
    
// Run on 1M elements on the CPU
add(N, x, y);
    
// Free memory
delete [] x; delete [] y;
return 0;
}

GPU上でのベクトル加算

GPU上で実行される関数をカーネル関数(kernel)と呼び、カーネル関数はCPUによって呼び出されます。

  • GPU 上のメモリ空間 (ビデオ メモリ) を解放します。
  • データをGPUにコピーする
  • カーネル関数の実行
  • 計算待ち
  • 結果をCPUに返す

GPUシリアル演算ベクトル加算

float *x = new float[N];
float *y = new float[N];
int size = N*sizeof(float);
float *d_x, *d_y; // device copies of x y
cudaMalloc((void **)&d_x, size);//GPU上开辟内存
cudaMalloc((void **)&d_y, size);//GPU上开辟内存
cudaMemcpy(d_x, x, size, cudaMemcpyHostToDevice);//CPU到GPU转移数据
cudaMemcpy(d_y, y, size, cudaMemcpyHostToDevice);//CPU到GPU转移数据
// Run kernel on GPU
add<<<1,1>>>(N, d_x, d_y);//调用内核代码,<<<1,1>>>表示使用单线程计算
// Copy result back to host
cudaMemcpy(y, d_y, size, cudaMemcpyDeviceToHost);//将结果返还给CPU
// Free memory
cudaFree(d_x); cudaFree(d_y);
delete [] x; delete [] y;


// GPU function to add two vectors
__global__ //添加关键字表示以下函数为内核函数
void add(int n, float *x, float *y) {
    
    
for (int i = 0; i < n; i++)
y[i] = x[i] + y[i];
}

並列計算を使用して計算速度を向上させたい場合は、複数のスレッドを使用して同時に計算する必要があります。カーネル関数を書き直す必要がある

// GPU function to add two vectors
__global__
void add(int n, float *x, float *y) {
    
    
int index = threadIdx.x;//CUDA线程的索引
y[index] = x[index] + y[index];
}

add<<<1,256>>>(N, d_x, d_y);//使用一个线程块中的256个线程进行计算

おすすめ

転載: blog.csdn.net/weixin_44659309/article/details/134368502