CUDA入門 > サンプル入門・初級編 > GPUで計算

GPUで計算


ソース
#include <stdio.h> #include <cutil.h> #define N 100 // カーネル(GPUの関数) __global__ void cudaKernel(int *gpu){ for(int i = 0; i < N; i++){ gpu[i] += 1; } } int main(int argc, char** argv){ int *x; int *gpu; //デバイスの初期化 CUT_DEVICE_INIT(argc, argv); // xの初期化 x = (int *)calloc(sizeof(int), N); for(int i = 0; i < N; i++){ x[i] = i; } // デバイス(GPU)のメモリ領域確保 CUDA_SAFE_CALL(cudaMalloc((void**)&gpu, sizeof(int)*N)); // ホスト(CPU)からデバイス(GPU)へ転送 CUDA_SAFE_CALL(cudaMemcpy(gpu, x, sizeof(int)*N, cudaMemcpyHostToDevice)); // スレッド数、ブロック数の設定(説明は他のページ) dim3 blocks(1,1); dim3 threads(1,1); // カーネル(GPUの関数)実行 cudaKernel<<< blocks, threads >>>(gpu); // デバイス(GPU)からホスト(CPU)へ転送 CUDA_SAFE_CALL(cudaMemcpy(x, gpu, sizeof(int)*N, cudaMemcpyDeviceToHost)); for(int i = 0; i < N; i++){ // x[i]の結果が変わっていれば出力 if(i != x[i]){ printf("x[%d] = %d\n", i, x[i]); } } // ホストメモリ解放 free(x); // デバイスメモリ解放 CUDA_SAFE_CALL(cudaFree(gpu)); // 終了処理 CUT_EXIT(argc, argv); return 0; }

実行例
x[0] = 1 x[1] = 2 x[2] = 3 x[3] = 4 x[4] = 5 (略)

ソースの説明
このソースは並列処理を行っていません
→並列処理に書き換えたソース

CUDA_SAFE_CALL()
これで囲むと、
通常の実行時は、引数として与えられたCUDA関数の呼び出し。
_DEBUGが定義されていると、引数の関数を呼び出し、その戻り値のエラーを検査し、
エラーの場合はエラーメッセージを出力する。

cudaMalloc(void** devPtr, size_t size)
デバイスのメモリ領域を確保します。
devPtr:デバイスメモリのポインタ
size:メモリのサイズ

cudaMemcpy(void* dst, const void* src, size_t count, enum cudaMemcpyKind kind)
ホストからデバイスにデータをコピーします。
dst:転送先のメモリアドレス
src:転送元のメモリアドレス
count:コピーするデータのサイズ
kind:転送の種類

▼転送の種類
cudaMemcpyHostToDevice:ホストからデバイスに転送
cudaMemcpyDeviceToHost:デバイスからホストに転送

関数名<<< ブロック数, スレッド数 >>>(引数);
カーネル関数呼び出しです。
ブロック数、スレッド数の説明は後ほど。