我有一个数据自动化系统的核心形式如下:
Void launch_kernel(..Arguments...)
{
int i = threadIdx.x
//Load required data
int temp1 = A[i];
int temp2 = A[i+1];
int temp3= A[i+2];
// compute step
int output1 = temp1 + temp2 + temp3;
int output2 = temp1 + temp3;
// Store the result
B[i] = output1;
C[i] = output2;
}
正如CUDA手册中所讨论的,GPU全局内存的一致性模型是而不是顺序。因此,存储器操作似乎是按照与原始程序顺序不同的顺序执行的。为了执行内存排序,CUDA提供了__threadfence()函数。但是,根据手册,该函数执行跨读和跨写的相对排序。引用手册中的一行:
调用线程在调用__threadfence_block()之前对共享内存和全局内存进行的所有写入都由调用线程的块中的所有线程观察到,就像调用线程在调用__threadfence_block()之后对共享内存和全局内存的所有写入一样;
因此很明显,__threadfence()不足以在读和写之间强制排序。
如何执行跨读和写入全局内存的顺序。或者,如何确保在执行上述内核的计算和存储部分之前,所有读取都是保证的完成。
发布于 2017-07-12 05:55:31
正如@RobertCrovella在他的评论中说的那样,您的代码会正常工作。
temp1、temp2和temp3是本地的(将使用寄存器或本地内存{每个线程全局内存})。这些不是在线程之间共享的,因此不存在任何并发问题。它们将像普通的C/C++一样工作。
A、B和C是全球性的。这些问题将受到同步问题的影响。A被用作只读,所以访问顺序无关紧要。B和C是写的,但是每个线程只写到它自己的索引中,所以它们的写入顺序并不重要。您对确保全局内存读取完成的关注是不必要的。在线程中,您的代码将按照写入的顺序执行,并为全局内存访问设置适当的暂存。出于性能原因,您可能不想这样做,但您可以这样做,如Bi = 0;Bi = 5;temp1 = Bi;并保证temp1为5。
在本例中,您不使用共享内存,但是它是线程块的本地内存,可以使用__syncthreads()在线程块内同步;
跨不同线程块的全局内存同步要求结束一个内核而启动另一个内核。NVidia声称他们正在研究一种更好的方式,在他们未来的方向之一,视频在youtube上。
https://stackoverflow.com/questions/45004448
复制相似问题