全局内存操作之前的CUDA __syncthreads()方法

时间:2015-03-06 18:07:47

标签: c++ cuda

我在使用__syncthreads()方法时遇到问题。我有这段代码:

__global__ void kernel(float *v1_out, float *v2_out, unsigned int dim){

     int tid = threadIdx.x;
     float v1[N], v2[M]; 

     if(tid < dim){  
        // -- Do some computations on v1 and v2 ... 
        // ... then syncthreads()
        __syncthreads();

       // -- Copy the results into global memory
       for(unsigned int j = 0; j < N; j++)
           v1_out[j + tid*N] = v1[j];
       for(unsigned int j = 0; j < M; j++)
           v2_out[j + tid*M] = v2[j];
     }
  }

不幸的是,当我从主机读取它时,这段代码给我的结果不正确,好像同步屏障不起作用。但是,如果我在虚拟向量中写入向量v1 [N]和v2 [M],比如v1_temp [N]和v2_temp [M],然后将这些向全局内存写入,内核会给出正确的结果。 &#34;工作&#34;代码是:

__global__ void kernel(float *v1_out, float *v2_out, unsigned int dim){

     int tid = threadIdx.x;
     float v1[N], v2[M], v1_temp[N], v2_temp[M]; 

     if(tid < dim){  
        // -- Do some computations on v1 and v2 ... 
       // ... then syncthreads()
       __syncthreads();

       // -- Fill the dummy vectors
       for(unsigned int j = 0; j < N; j++)
           v1_temp[j] = v1[j];
       for(unsigned int j = 0; j < M; j++)
           v2_temp[j] = v2[j];

       // -- Copy the results into global memory
       for(unsigned int j = 0; j < N; j++)
           v1_out[j + tid*N] = v1_temp[j];
       for(unsigned int j = 0; j < M; j++)
           v2_out[j + tid*M] = v2_temp[j];
     }
  }

我只启动一个块,而我现在__syncthreads()应该确保块中的所有线程都在它之前执行了指令。现在我无法弄清楚两个内核行为的差异以及为什么我需要在将数据写入全局内存之前读取数据,有人可以解释一下吗?提前谢谢。

1 个答案:

答案 0 :(得分:2)

您基本上在内核中调用未定义的行为 - 内部__syncthreads()同步块中的所有线程; 通常,执行只能在块中的所有线程到达时继续它。但是,你有一个条件,它可以成功一些线程,而失败的其他线程。因此,并非所有线程都到达__syncthreads()

你应该将它移出条件。也就是说,关闭条件之前,同步并再次打开它:

 if(tid < dim){  
    // -- Do some computations on v1 and v2 ... 
 }

 __syncthreads();

 if(tid < dim) {
   // -- Copy the results into global memory
   for(unsigned int j = 0; j < N; j++)
       v1_out[j + tid*N] = v1[j];
   for(unsigned int j = 0; j < M; j++)
       v2_out[j + tid*M] = v2[j];
 }