单个线程内的CUDA内存操作顺序

时间:2014-01-18 14:04:06

标签: cuda

从CUDA编程指南(v.5.5):

  

CUDA编程模型假定设备具有弱排序   记忆模型,即:

     
      
  • CUDA线程将数据写入共享内存,全局内存,页锁定主机内存或对等设备内存的顺序   不一定是观察数据的顺序   由另一个CUDA或主持人线程编写;
  •   
  • CUDA线程从共享内存,全局内存,页面锁定主机内存或对等设备内存中读取数据的顺序   不一定是读指令出现的顺序   指令程序彼此独立
  •   

但是,我们是否有保证从单线程看到的(依赖)内存操作实际上是否一致?如果我这样做 - 说:

arr[x] = 1;
int z = arr[y];

其中x恰好等于y,并且没有其他线程触及内存,我是否有保证 z为1?或者我是否还需要在这两个操作之间放置一些volatile或障碍?


回应Orpedo的回答

  

如果您的编译器没有将代码所声明的功能编译为机器代码中的相同功能,那么编译器要么已损坏,要么您尚未考虑优化...

我的问题是允许优化(由编译器或硬件完成)? 它可能发生---例如--- store指令是非阻塞的,并且以某种方式跟随的load指令由内存控制器更快管理排队store

我不知道CUDA硬件。我有保证,以上情况永远不会发生吗?

3 个答案:

答案 0 :(得分:3)

CUDA编程指南只是声明,您无法预测线程的执行顺序,但每个线程仍将作为顺序线程运行。 在您说明的示例中,x和y相同且NO OTHER THREAD触及内存,您必须保证z = 1。 在这里,重点是,如果您对同一数据(例如数组)执行多个线程操作,则无法保证线程#9在#10之前执行。

举个例子:

__device__ void sum_all(float *x, float *result, int size N){
  x[threadId.x] = threadId.x;
  result[threadId.x] = 0;
  for(int i = 0; i < N; i++)
    result[threadId.x] += x[threadID.x];
}

这里我们有一些哑函数,它应该用m ... n中的数字填充共享数组(x)(从一个数字读取到另一个数字),然后总结已放入数组的数字和将结果存储在另一个数组中。 鉴于您的最低索引线程是枚举线程#0,您可能希望代码第一次运行时此代码x应该包含

x [] = {0,0,0 ... 0}且结果[] = {0,0,0 ... 0}

下一个线程#1

x [] = {0,1,0 ... 0}且结果[] = {0,1,0 ... 0}

下一个线程#2

x [] = {0,1,2 ... 0}且结果[] = {0,1,3 ... 0}

等等。 但这不能保证。你不知道是否例如线程#3首先运行,因此在线程#0运行之前更改数组x []。在执行代码时,您实际上甚至不知道阵列是否被其他线程更改。

答案 1 :(得分:1)

我不确定,如果在CUDA文档中明确说明(我不希望这样做),因为这是计算的基本原则。基本上你要问的是,如果在GFX上运行你的代码会改变代码的功能。

GPU的核心通常与CPU的核心相同,只是控制算法较少,指令集较小,通常只支持单精度。 在CUDA-GPU中,每个Warp有一个程序计数器(32个同步核心部分)。像CPU一样,程序计数器在每条指令后增加一个地址元素的大小,除非你有分支或跳转。这给出了程序的顺序流程,并且这不能改变。 分支和跳转只能由运行在核心上的软件引入,因此由编译器决定。编译器优化实际上可以改变代码的功能,但仅限于代码实现的情况和错误的#34;关于编译器 简而言之 - 无论是在CPU还是GPU上执行,您的代码将始终按照内存中的顺序执行。如果您的编译器没有将代码所声明的功能编译为机器代码中的相同功能,那么编译器要么已损坏,要么您还没有考虑优化...

希望这很清楚:)

答案 2 :(得分:0)

据我了解,您基本上都在询问CUDA编译器中是否遵守了内存依赖性和别名分析信息。

这个问题的答案是,假设CUDA编译器没有错误,是的,因为正如Robert所说,CUDA编译器使用LLVM和两个基本模块(目前,我真的不要认为他们可以被管道排除):

这两个过程检测可能指向同一地址的内存位置,并对变量使用实时分析(甚至在块范围之外)以避免危险的优化(例如,无法写入在下次读取之前的实时变量,数据可能仍然有用)。

我不知道编译器的内部结构,但假设(与任何其他合理信任的编译器一样)它会尽力做到没有错误,那里发生的分析应该没有打扰你,并向你保证至少在理论上你刚才提出的例子(即依赖加载比商店更快)是不可能发生的。

你能保证什么?除了公司正在使用编译器这一事实外,还有一些免责声明,以防它出现异常情况:)

另外:除了编译器主题外,指令执行还取决于硬件规范。在这种情况下,SIMT硬件指令发布单元 (CFR)。 http://www.csl.cornell.edu/~cbatten/pdfs/kim-simt-vstruct-isca2013.pdf以及所有参考文件以获取更多信息