2017-08-11 38 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 
$