Parallel processing 将数据从全局内存移动到共享内存是否会使线程停滞? __共享浮点数smem[2]; smem[0]=全局_内存[0]; smem[1]=全局_存储器[1]; /*进程smem[0]*/ /*过程smem[1]*/

Parallel processing 将数据从全局内存移动到共享内存是否会使线程停滞? __共享浮点数smem[2]; smem[0]=全局_内存[0]; smem[1]=全局_存储器[1]; /*进程smem[0]*/ /*过程smem[1]*/,parallel-processing,cuda,nvidia,Parallel Processing,Cuda,Nvidia,我的问题是,smem[1]=全局_内存[1];smem[0]上的块计算? 在中,他们说内存读取不会暂停线程,直到读取的数据被使用。将其存储到共享内存是否与使用数据一样重要?我是否应该这样做: LDG Rx, [Ry] LDG Rw, [Ry+1] STS [Rz], Rx STS [Rz+1], Rw __共享浮点数smem[2]; 浮点a=全局_内存[0]; 浮点b=全局_内存[1]; smem[0]=a; /*过程smem[0]*/ smem[1]=b; /*过程smem[1]*/

我的问题是,smem[1]=全局_内存[1];smem[0]上的块计算? 在中,他们说内存读取不会暂停线程,直到读取的数据被使用。将其存储到共享内存是否与使用数据一样重要?我是否应该这样做:

LDG  Rx, [Ry]
LDG  Rw, [Ry+1]
STS  [Rz], Rx
STS  [Rz+1], Rw
__共享浮点数smem[2]; 浮点a=全局_内存[0]; 浮点b=全局_内存[1]; smem[0]=a; /*过程smem[0]*/ smem[1]=b; /*过程smem[1]*/
或者是编译器为我做的?但是它会使用额外的寄存器吗?

是的,在一般情况下,这会阻塞CUDA线程:

smem[0] = global_memory[0];
原因是此操作将分为两个步骤:

LDG  Rx, [Ry]
STS  [Rz], Rx
第一条SASS指令从全局内存加载。此操作不会阻止CUDA线程。它可以发送到LD/ST单元,线程可以继续。但是,该操作Rx的寄存器目标被跟踪,如果任何指令需要使用来自Rx的值,CUDA线程将在该点暂停

当然,下一条指令是STS store共享指令,它将使用来自Rx的值,因此CUDA线程将在该点暂停,直到满足全局负载

当然,编译器可能会对指令进行重新排序,以便STS指令稍后出现,但这并不能保证。不管怎样,只要编译器对STS指令进行排序,CUDA线程就会在该点暂停,直到全局加载完成。对于您给出的示例,我认为编译器很可能会创建如下代码:

LDG  Rx, [Ry]
LDG  Rw, [Ry+1]
STS  [Rz], Rx
STS  [Rz+1], Rw
换句话说,我认为编译器可能会组织这些加载,以便在可能的暂停发生之前发出两个全局加载。然而,这并不能保证,代码的具体行为只能通过研究实际的SASS来推断,但在一般情况下,我们应该假设线程暂停的可能性

是的,如果您可以按照代码中显示的方式分解加载和存储,则此操作:

float b = global_memory[1];
smem[0] = a;
/* process smem[0]*/
不应阻止此操作:

float b = global_memory[1];
smem[0] = a;
/* process smem[0]*/

话虽如此,CUDA在CUDA 11中引入了一种新的机制来解决这种情况,该机制由计算能力为8.0及更高的设备支持,因此,目前所有的安培GPU都支持。此新功能称为。它允许在不暂停CUDA线程的情况下继续执行这些复制操作。但是,此功能需要正确使用屏障,以确保当您需要实际使用共享内存中的数据时,它是存在的。

是的,在一般情况下,这将阻止CUDA线程:

smem[0] = global_memory[0];
原因是此操作将分为两个步骤:

LDG  Rx, [Ry]
STS  [Rz], Rx
第一条SASS指令从全局内存加载。此操作不会阻止CUDA线程。它可以发送到LD/ST单元,线程可以继续。但是,该操作Rx的寄存器目标被跟踪,如果任何指令需要使用来自Rx的值,CUDA线程将在该点暂停

当然,下一条指令是STS store共享指令,它将使用来自Rx的值,因此CUDA线程将在该点暂停,直到满足全局负载

当然,编译器可能会对指令进行重新排序,以便STS指令稍后出现,但这并不能保证。不管怎样,只要编译器对STS指令进行排序,CUDA线程就会在该点暂停,直到全局加载完成。对于您给出的示例,我认为编译器很可能会创建如下代码:

LDG  Rx, [Ry]
LDG  Rw, [Ry+1]
STS  [Rz], Rx
STS  [Rz+1], Rw
换句话说,我认为编译器可能会组织这些加载,以便在可能的暂停发生之前发出两个全局加载。然而,这并不能保证,代码的具体行为只能通过研究实际的SASS来推断,但在一般情况下,我们应该假设线程暂停的可能性

是的,如果您可以按照代码中显示的方式分解加载和存储,则此操作:

float b = global_memory[1];
smem[0] = a;
/* process smem[0]*/
不应阻止此操作:

float b = global_memory[1];
smem[0] = a;
/* process smem[0]*/
话虽如此,CUDA在CUDA 11中引入了一种新的机制来解决这种情况,该机制由计算能力为8.0及更高的设备支持,因此,目前所有的安培GPU都支持。此新功能称为。它允许在不暂停CUDA线程的情况下继续执行这些复制操作。但是,此功能需要正确使用屏障,以确保当您需要实际使用共享内存中的数据时,它是存在的