cuda學習筆記(1)

1.基本流程

cuda代碼(.cu)的目的是並行運算。只要在c/c++代碼中調用以 __ global__爲關鍵字修飾的函數( __ global __ void function( type *InputArrayA, type *InputArrayB, type *OutputArrayA) ),稱爲核函數,代碼經nvcc編譯,識別到核函數就會編譯成gpu指令碼; 調用該函數時,要在函數名稱加上 <<<blocksPerGrid, threadsPerBlock>>> ( function<<<blocksPerGrid, threadsPerBlock>>>( type *InputArrayA, type *InputArrayB, type *OutputArrayA) )。不過,gpu 只能操作gpu上的變量,所以在調用 __ global __ 函數之前,先用 cudaMalloc 申請好在cuda變量內存(__global函數的參數:input array,output array),並用 cudaMemcpy (cudaMemcpyHostToDevice) 賦值輸入array。待函數執行完成後,執行結果保存在輸出array中,用 cudaMemcpy (cudaMemcpyDeviceToHost) 把執行結果從gpu內存中copy到cpu中,並行計算完成,用 cudaFree 釋放之前申請的cuda變量內存。 以上就是cpu代碼中調用gpu的流程。

1.1 blocksPerGrid, threadsPerBlock 說明

cuda 結構
調用 cuda 核函數需要指定調用多少個block,每個block包含多少個thread。其中,多個block組成一個 grid . 共調用了 blocksPerGrid*threadsPerBlock 個並行執行的線程,所以要在cuda核函數中明確的指定每個線程執行時對應的array index。注意:thread, block有.x, .y二維數據,但有時只用其中一維.x 。下面將給出一個簡單的demo,執行 C=A+B ( c[i] = a[i] + b[i] )運算。

example1: naive_add.cu

#include "../common/book.h"

#define N   10

__global__ void add( int *a, int *b, int *c ) 
{
    int tid = blockIdx.x;    // this thread handles the data at its thread id
    if (tid < N)
        c[tid] = a[tid] + b[tid];
}

int main( void ) 
{
    int a[N], b[N], c[N];
    int *dev_a, *dev_b, *dev_c;

    // allocate the memory on the GPU
    HANDLE_ERROR( cudaMalloc( (void**)&dev_a, N * sizeof(int) ) );
    HANDLE_ERROR( cudaMalloc( (void**)&dev_b, N * sizeof(int) ) );
    HANDLE_ERROR( cudaMalloc( (void**)&dev_c, N * sizeof(int) ) );

    // fill the arrays 'a' and 'b' on the CPU
    for (int i=0; i<N; i++) 
    {
        a[i] = -i;
        b[i] = i * i;
    }

    // copy the arrays 'a' and 'b' to the GPU
    HANDLE_ERROR( cudaMemcpy( dev_a, a, N * sizeof(int),
                              cudaMemcpyHostToDevice ) );
    HANDLE_ERROR( cudaMemcpy( dev_b, b, N * sizeof(int),
                              cudaMemcpyHostToDevice ) );
    //N blocks, 1 thread per block for N length arrays parallel computation(add)
    add<<<N,1>>>( dev_a, dev_b, dev_c );

    // copy the array 'c' back from the GPU to the CPU
    HANDLE_ERROR( cudaMemcpy( c, dev_c, N * sizeof(int),
                              cudaMemcpyDeviceToHost ) );

    // display the results
    for (int i=0; i<N; i++)
    {
        printf( "%d + %d = %d\n", a[i], b[i], c[i] );
    }

    // free the memory allocated on the GPU
    HANDLE_ERROR( cudaFree( dev_a ) );
    HANDLE_ERROR( cudaFree( dev_b ) );
    HANDLE_ERROR( cudaFree( dev_c ) );

    return 0;
}
發佈了27 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章