CUDA原子操作线程级还是块级?

CUDA原子操作线程级还是块级?,cuda,atomic,Cuda,Atomic,何时发生在块级别序列化的原子操作? 如果我有以下代码: __global__ void sum (int *input){ if ( threadIdx.x == 0) __shared__ int result = 0; __syncthreads(); atomicAdd(result,input[threadIdx.x+blockDim.x*blockId.x]); } 此序列化是否发生在块级别? 我一般不理解“块级序列化”的含义,因为据我所知,操作总是

何时发生在块级别序列化的原子操作? 如果我有以下代码:

__global__ void sum (int *input){

   if ( threadIdx.x == 0) 
     __shared__ int result = 0;
   __syncthreads(); 
   atomicAdd(result,input[threadIdx.x+blockDim.x*blockId.x]);
}
此序列化是否发生在块级别?
我一般不理解“块级序列化”的含义,因为据我所知,操作总是由线程执行。

CUDA中有两种原子操作:

  • 那些在全局内存上运行的
  • 那些在共享内存上运行的
全局内存对网格/内核中的所有线程都是“可见的”(即,只有一个全局内存逻辑视图,网格中的所有线程共享同一视图),因此全局原子创建(根据需要)设备范围内的序列化,通常(*)在二级缓存中得到解析,这是一个设备范围的资源

共享内存在逻辑上是每个线程块的资源(不同的线程块具有不同的共享内存逻辑视图,即它们自己的共享内存“私有副本”),在物理上是每个SM的资源。由于共享内存在逻辑上是每个线程块的资源,因此只有特定线程块中的线程具有相同的共享内存“视图”或逻辑副本。因此,在执行共享内存原子时,可能发生的“序列化”是线程块级别的序列化(与设备范围的序列化相比)。只有同一threadblock中的线程才能竞争对特定共享内存位置的访问,因为共享内存在逻辑上是每个threadblock的单独实体

在单个线程中,所有指令都是逻辑序列化的,并且没有仅在单个线程中操作的原子操作的概念。原子可以(逻辑上)跨属于单个线程块的线程运行,也可以跨网格/内核中的所有线程运行

当然,所有的原子操作都涉及到线程之间为了访问特定位置而进行的竞争。重要的区别在于它们是在竞争对共享内存中某个位置的访问,还是对全局内存中某个位置的访问

从语法上讲,共享内存原子和全局内存原子之间没有区别(在CUDA C++中,即CUDA PTX或SASS是不同的情况)。原子操作是在共享内存还是全局内存上进行的确定取决于传递给提供更新位置的原子的指针的类型(即数值或逻辑关联)。如果该指针“指向”共享内存,则它是一个共享内存原子。如果该指针“指向”全局内存,则它是一个全局内存原子

原子是


(*)最近,
nvcc
编译器驱动程序获得了识别某些原子模式的能力,这些模式是扭曲的,并且可以执行。当编译器选择此实现时,可以认为当编译器选择该惯用语时,warp中的原子竞争在二级缓存中没有得到解决。

CUDA中有两种原子操作:

  • 那些在全局内存上运行的
  • 那些在共享内存上运行的
全局内存对网格/内核中的所有线程都是“可见的”(即,只有一个全局内存逻辑视图,网格中的所有线程共享同一视图),因此全局原子创建(根据需要)设备范围内的序列化,通常(*)在二级缓存中得到解析,这是一个设备范围的资源

共享内存在逻辑上是每个线程块的资源(不同的线程块具有不同的共享内存逻辑视图,即它们自己的共享内存“私有副本”),在物理上是每个SM的资源。由于共享内存在逻辑上是每个线程块的资源,因此只有特定线程块中的线程具有相同的共享内存“视图”或逻辑副本。因此,在执行共享内存原子时,可能发生的“序列化”是线程块级别的序列化(与设备范围的序列化相比)。只有同一threadblock中的线程才能竞争对特定共享内存位置的访问,因为共享内存在逻辑上是每个threadblock的单独实体

在单个线程中,所有指令都是逻辑序列化的,并且没有仅在单个线程中操作的原子操作的概念。原子可以(逻辑上)跨属于单个线程块的线程运行,也可以跨网格/内核中的所有线程运行

当然,所有的原子操作都涉及到线程之间为了访问特定位置而进行的竞争。重要的区别在于它们是在竞争对共享内存中某个位置的访问,还是对全局内存中某个位置的访问

从语法上讲,共享内存原子和全局内存原子之间没有区别(在CUDA C++中,即CUDA PTX或SASS是不同的情况)。原子操作是在共享内存还是全局内存上进行的确定取决于传递给提供更新位置的原子的指针的类型(即数值或逻辑关联)。如果该指针“指向”共享内存,则它是一个共享内存原子。如果该指针“指向”全局内存,则它是一个全局内存原子

原子是


(*)最近,
nvcc
编译器驱动程序获得了识别某些原子模式的能力,这些模式是扭曲的,并且可以执行。当编译器选择此实现时,可以认为当编译器选择该惯用语时,warp中的原子竞争在二级缓存中没有得到解决。

您似乎提出了与标题中不同的问题。有什么问题?原子操作?理解块级序列化?发生了什么?我知道为什么共享变量上的原子外接程序是ki