【问题标题】:cuda constant memory referencecuda 常量内存引用
【发布时间】:2012-10-17 11:39:57
【问题描述】:

我在常量内存中有一个数组(它是一个全局变量),并通过函数调用 cudaGetSymbolAddress 获得了对它的引用。当我使用这个引用来获取常量数据而不是使用全局变量时,我的内核运行缓慢。这是什么原因?

__constant__ int g[2] = {1,2};
// __device__ int g[2] = {1,2};

// kernel: use by reference
__global__ void add_1( int *a, int *b, int *c, int *f )
{
    int tid = blockIdx.x * blockDim.x + threadIdx.x;
    c[tid] = f[0] * a[tid] + f[1] * b[tid];
}

// kernel: use global variable
__global__ void add_2( int *a, int *b, int *c, int *f )
{
    int tid = blockIdx.x * blockDim.x + threadIdx.x;
    c[tid] = g[0] * a[tid] + f[1] * b[tid];
}

int main()
{
    ......
    // a,b,c are large arrays in device memory of size 40960.

    int *f;
    cudaGetSymbolAddress( (void **)&f, (char *)&g);

    add_1 <<< 160, 256 >>> ( a, b, c, f );

    ......
}

这是示例代码,warp 中的所有线程同时加载相同的位置。注释代码是通过直接访问常量内存

解释为什么不使用常量内存缓存(by talonmies

原因是缺少常量缓存。 仅当编译器在显式标记为处于常量状态空间中的变量上发出特定的 PTX 指令 (ld.const) 时,才会发生缓存访问。编译器知道这样做的方式是在声明变量__constant__ 时——它是一个影响代码生成的静态编译时属性。运行时不能发生相同的过程。

如果您在全局内存中传递一个指针,而编译器无法确定该指针在常量状态空间中,则它不会生成正确的 PTX 以通过常量缓存访问该内存。因此访问速度会变慢。

未回答的问题

为什么即使数组g 被声明为__device__ 变量,引用它时代码也会变慢。通过查看PTX 代码,将全局内存加载到寄存器:

  • 使用了ld.global.s32的2条指令,将4个字节加载到寄存器中。 (在代码中使用参考)
  • 使用ld.global.v2.s32的1条指令,将8个字节加载到2个寄存器中,(在使用全局变量的代码中)

有什么区别,任何文档参考都将不胜感激?

【问题讨论】:

  • 我猜你没有利用常量特性。您如何访问全局和常量内存中的数据?您的代码的 sn-p 将帮助我们为您提供更好的答案。
  • pQB 是对的。我刚刚看到了 talonmies 的回答,根据给出的信息,无法确定哪一个适用于您的问题。另外,你的 GPU 是什么计算能力?
  • @tera 计算能力为 1.3
  • 我在代码中根本看不到 __constant__ 声明。你怎么称呼内核?
  • @tera 我更改了相关代码。

标签: cuda gpu-constant-memory


【解决方案1】:

与全局内存不同,如果对常量内存的访问不统一(计算能力 1.x 的一半)warp 的所有线程都访问相同的地址,则对常量内存的访问将被序列化(拆分为多个事务)。

因此,如果访问可能是统一的,则仅使用常量内存。

【讨论】:

  • 我不认为这是一个非统一访问,warp中的所有线程都请求加载指令的相同地址位置。
  • 确实如此。我最初认为由 [tid] 索引的访问将是对常量内存的访问。您能否提供来自cuobjdump -sass -fun add 的反汇编内核代码,以便我们更好地了解发生了什么?
  • 您是否尝试过上面显示的没有其他程序的隔离代码是否仍然显示问题?问题可能出在我们从这里看不到的其他东西上……
  • 是的..这实际上是我正在试验的一个非常简单的例子。
  • 你能发布完整的例子吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多