cuda多个内存访问

时间:2011-09-14 13:34:48

标签: gpgpu cuda

请在以下内核中解释内存访问的工作原理:

__global__ void kernel(float4 *a)
{
     int tid = blockIdx.x * blockDim.x + threadIdx.x;

     float4 reg1, reg2;
     reg1 = a[tid]; //each thread reads a unique memory location

     for(int i = 0; i < totalThreadsNumber; i++)
     {  
          reg2 = a[i]; //all running threads start reading 
                       //the same global memory location
          //some computations
     }

     for(int i = 0; i < totalThreadsNumber; i++)
     {
          a[i] = reg1; // all running threads start writing 
                       //to the same global memory location
                       //race condition
     }
}

它在第一个循环中如何工作?有序列化吗?我假设第二个循环导致线程序列化(仅在warp?中)并且结果是未定义的。

1 个答案:

答案 0 :(得分:2)

保留我对Fermi(sm_2x)的解释,对于较旧的硬件内存访问,则为半经线。

在第一个循环(读取)中,整个warp从同一地址读取到局部变量。这导致“广播”。由于Fermi具有L1高速缓存,因此将加载一个高速缓存行,或者直接从高速缓存中获取数据(用于后续迭代)。换句话说,没有序列化。

在第二个循环(写入)中,哪个线程获胜是未定义的 - 就像任何多线程编程模型一样,如果多个线程写入同一位置,则程序员负责了解竞争条件。您无法控制块中的哪个warp将最后执行,也无法控制最后一个warp中的哪个线程将完成写入,因此您无法预测最终值将是什么。