【问题标题】:Why variables in thread's block have the same memory address? Cuda为什么线程块中的变量具有相同的内存地址?库达
【发布时间】:2021-02-25 12:27:32
【问题描述】:

我想知道为什么它们有相同的内存地址,如果我没记错的话,每个线程都有一个自己的创建变量的副本:

__global__ void
Matrix_Multiplication_Shared(
   const int* const Matrix_A, 
   const int* const Matrix_B, 
         int* const Matrix_C)
{   
    const int sum_value = threadIdx.x;
    printf("%p \n", &sum_value);
}

输出:

我正在考虑一个线程块的情况,例如有 2 个或更多线程。

【问题讨论】:

  • 在我看来,没有线索可以添加更多代码,这很愚蠢
  • 仅在需要时,我可以添加内核执行行
  • 您正在打印automatic 变量的地址。这是在当前线程输入范围时创建的。可能这只是在调用函数时在堆栈上创建。因此,如果您只是在循环中重复调用此函数,它将“可能”始终具有相同的地址,因为堆栈没有更改。您是否在示例中使用不同的线程调用该函数?
  • 是的,但是如果我要打印一个值,那么我会打印出不同的值

标签: cuda nvidia


【解决方案1】:

NVIDIA GPU 有多个地址空间。

指针使用的主要虚拟地址空间称为通用地址空间。在通用地址空间内是本地内存和共享内存的窗口。通用地址空间的其余部分是全局地址空间。 PTX 和 GPU 指令集支持基于 0 访问本地和共享内存地址空间的附加指令。

一些自动变量和堆栈内存在本地内存地址空间中。全局内存和本地内存之间的主要区别在于,本地内存的组织方式是通过连续的线程 ID 访问连续的 32 位字。如果每个线程从相同的本地内存偏移量读取或写入,则内存访问完全合并。

在 PTX 中,本地内存通过 ld.local 和 st.local 访问。

在 GPU SASS 中,指令有两种形式:

  1. LDL、STL 是对本地内存的直接访问,以基于 0 的偏移量给出
  2. LD、ST 可用于通过通用本地内存窗口访问本地内存。

当您获取变量的地址时,将返回通用地址空间地址。每个线程都看到与通用本地内存窗口基指针相同的偏移量。加载存储单元会将基于 0 的偏移量转换为每个线程唯一的全局地址。

欲了解更多信息,请参阅:

【讨论】:

  • 格雷格,再次感谢您的贡献。我已经使用这项技术将近 13 年了,每次您在这里发帖时,我仍然能学到一些东西。
猜你喜欢
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
  • 2014-04-24
  • 1970-01-01
  • 2023-03-03
  • 2012-08-06
  • 1970-01-01
  • 2016-12-18
相关资源
最近更新 更多