CUDA採坑之路

1.cudaMalloc來回拷貝東西的時候一定要注意內存大小的問題,不然的話可能會出問題。

2.CUDA主機函數中可以使用c的語法,可以使用printf進行調試。

3.printf有的時候可以起到__syncthreads()的作用,所以有的時候如果加了printf能用的話,很可能是忘了加同步了。

4.在改變任何所有的核函數統一用到的變量之前一定要加__syncthreads(),如下面的例子中,因爲每次i更新後所執行的操作都必須要求i爲上一次的值得時候的操作都執行完成,如果不加同步,就會造成執行順序無法控制,最終造成結果的錯誤。

 for (int i = blockDim.x / 2; i >= 1; i /= 2) {
        if ( threadIdx.x < i) {
            c_cache[ threadIdx.x] += c_cache[ threadIdx.x + i];
            __syncthreads();
        }
    }

5.double有的時候比較佔空間,所以,炸了的話,換float就行了。

6.對於texture一定要在覈函數(使用到它)之前定義。同時對於texture的理解,把a(texture變量)和b(全局變量)綁定了候,每次在執行核函數的時候會把b拷貝到a中,在這次核函數執行的過程中,對於b中的內容仍然可以修改,但是a中的內容是不變的。然後對於下次調用核函數的時候,a會再次把b拷貝,這次的就是上次對b修改後的內容。示例代碼

#include "cuda_runtime.h"
#include"cuda.h"
#include "device_launch_parameters.h"
#include "device_functions.h"
#include <stdio.h>
#include <iostream>
using namespace std;
#define N 10
texture<float> test;
#define mins(a,b)(a<b?a:b)
#define threadsperblock 16
const int blocknum=mins(int((N +threadsperblock)/ threadsperblock), 32);

__global__ void kernel(float *a, float *b)
{
    int id = threadIdx.x + blockIdx.x * blockDim.x;
    a[id] = a[id] + b[id];
    b[id] = tex1Dfetch(test, id);
    printf("now a[%d] %f  texture[%d] %f\n", id, a[id], id, tex1Dfetch(test, id));   
}

int main()
{
    float a[N], b[N];
    float* da, * db;
    for (int i = 0; i < N; i++) {
        a[i] = i;
        b[i] = i *2;
    }
    cout << cudaMalloc((void**)&da, N * sizeof(float)) << endl;;
    cout << cudaMalloc((void**)&db, N * sizeof(float)) << endl;;
    for (int z = 0; z < 2; z++) {
        cout << cudaMemcpy(da, a, N * sizeof(float), cudaMemcpyHostToDevice) << endl;
        cout << cudaMemcpy(db, b, N * sizeof(float), cudaMemcpyHostToDevice) << endl;

        cudaBindTexture(NULL, test, da, N * sizeof(float));
        kernel << <blocknum, threadsperblock >> > (da, db);

        cudaMemcpy(a, da, N * sizeof(float), cudaMemcpyDeviceToHost);
        cudaMemcpy(b, db, N * sizeof(float), cudaMemcpyDeviceToHost);

        for (int i = 0; i < N; i++) {
            cout << a[i] << "," << b[i] << endl;
        }
        cout << endl;
    }
    cudaFree(da);
    cudaFree(db);
    cudaUnbindTexture(test);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章