2017-08-11 50 views
-1

我寫了一個函數swap來方便地交換設備數組指針,但它不工作,我假設我交換交換功能中的本地數組指針,而不是我傳遞給它的那些指針。CUDA - 如何交換設備數組指針?

__global__ void device_add_one(float *A, float *B) 
{ 
    for (int index = blockIdx.x * blockDim.x + threadIdx.x; 
     index < N; 
     index += blockDim.x * gridDim.x) 
    { 
     // just for the example 
     B[index] = A[index] + 1; 
    { 
} 

void swap(float *a, float *b) 
{ 
    float *temp = a; 
    a = b; 
    b = temp; 
} 

void loop(float *host_array, int size, int loops) 
{ 
    cudaMalloc(&A, (size * sizeof(float)); 
    cudaMalloc(&B, (size * sizeof(float)); 

    cudaMemcpy(A, host_array, (size * sizeof(float), cudaMemcpyHostToDevice); 

    for (int i = 0; i < loops; i++) { 
     device_add_one<<< 1, 254 >>>(A, B); 

     // swap pointers like this does not work 
     swap(A, B); 

     /* This works: 
     float *temp = a; 
     a = b; 
     b = temp; 
     */ 
    } 

    cudaMemcpy(host_array, A, (size * sizeof(float), cudaMemcpyDeviceToHost); 
} 
+3

你的第一種方法會奏效。 [這裏](https://stackoverflow.com/questions/43482463/cuda-program-not-working-as-fast-as-expected/43485665#43485665)就是一個例子,還有其他的例子。你沒有展示完整的代碼,也沒有解釋爲什麼你認爲它不工作,所以不知道這裏說什麼。當你說什麼不起作用時,你應該[提供](https://stackoverflow.com/help/on-topic)[mcve]。 –

+1

從目前看來,當前的解決方案(交換循環中的指針)*應該工作 - 它在哪種方式下不工作? – Marco13

+0

您發佈的代碼有各種語法錯誤。你無法編譯該代碼。如果各種語法錯誤是固定的,並且根據需要提供了適當的'main'函數和其他定義,那麼根據我的測試,您顯示的代碼工作正常。在這種狀態下,這個問題幾乎是無法回答的,SO提供了一個專門針對這種情況的投票 - 關閉原因。 –

回答

1

您交換指針的函數調用方法不起作用,因爲您正在使用按值傳遞。這是一個普通的C/C++編程概念,並非CUDA獨有的。

當你傳遞變量(包括指針,在這種情況下)的功能by value

void swap(float *a, float *b) 

的C中傳遞按值機制創建的函數參數的本地副本,使用的函數中身體。這些參數的更改不顯示在調用上下文中。要解決這個問題,一個簡單的方法是通過按引用(C++):

void swap(float* &a, float* &b) 

下面是一個樣例:

$ cat t393.cu 
#include <stdio.h> 

const int N = 1000; 
float *A, *B; 

__global__ void device_add_one(float *A, float *B) 
{ 
    for (int index = blockIdx.x * blockDim.x + threadIdx.x; 
     index < N; 
     index += blockDim.x * gridDim.x) 
    { 
     // just for the example 
     B[index] = A[index] + 1; 
    } 
} 
void swap(float* &a, float* &b){ 
    float *temp = a; 
    a = b; 
    b = temp; 
} 

void loop(float *host_array, int size, int loops) 
{ 
    cudaMalloc(&A, size * sizeof(float)); 
    cudaMalloc(&B, size * sizeof(float)); 

    cudaMemcpy(A, host_array, (size * sizeof(float)), cudaMemcpyHostToDevice); 

    for (int i = 0; i < loops; i++) { 
     device_add_one<<< 1, 254 >>>(A, B); 

     // swap pointers 
     swap(A, B); 
     //float *temp = A; 
     //A = B; 
     //B = temp; 
    } 

    cudaMemcpy(host_array, A, (size * sizeof(float)), cudaMemcpyDeviceToHost); 
} 

int main(){ 

    float *data = (float *)malloc(N*sizeof(float)); 
    for (int i = 0; i<N; i++) data[i] = i & 3; // fill with 0 1 2 3 0 1 2 3... 
    loop(data, N, 100); 
    for (int i = 0; i<20; i++) printf("%f ", data[i]); 
    printf("\n"); 
    return 0; 
} 
$ nvcc -arch=sm_61 -o t393 t393.cu 
$ cuda-memcheck ./t393 
========= CUDA-MEMCHECK 
100.000000 101.000000 102.000000 103.000000 100.000000 101.000000 102.000000 103.000000 100.000000 101.000000 102.000000 103.000000 100.000000 101.000000 102.000000 103.000000 100.000000 101.000000 102.000000 103.000000 
========= ERROR SUMMARY: 0 errors 
$