本地的,全球的,恒定的和共享内存

时间:2012-08-02 20:08:23

标签: cuda gpu-shared-memory gpu-constant-memory gpu-local-memory

我阅读了一些引用本地内存的CUDA文档。 (这主要是早期文档。)设备属性报告本地mem大小(每个线程)。 “本地”记忆是什么意思?什么是'本地'记忆? “本地”记忆在哪里?如何访问“本地”内存?它是__device__内存,没有?

设备属性还报告:全局,共享和&常数mem大小。 这些陈述是否正确: 全局内存为__device__内存。它具有网格范围和网格(内核)的生命周期。 常量内存为__device__ __constant__内存。它有网格范围和网格(内核)的生命周期。 共享内存为__device__ __shared__内存。它有单块范围和该块(线程)的生命周期。

我认为共享内存是SM内存。即只有那个SM可以直接访问的内存。资源相当有限。 SM是不是一次分配了一堆块?这是否意味着SM可以交错执行不同的块(或不是)?即运行阻止* A *线程,直到它们停止。然后运行block * B *线程,直到它们停止。然后再次交换回阻止* A *线程。或者SM是否为块* A *运行一组线程,直到它们停止为止。然后交换另一组块* A *线程。此交换继续,直到块* A *耗尽。然后,只有这样才能在块* B *上开始工作。 因为共享记忆,我问。如果单个SM从2个不同的块交换代码,那么SM如何快速交换/分出共享内存块? (我认为后来的senerio是真的,并且没有交换共享内存空间。阻止* A *运行直到完成,然后阻止* B *开始执行。注意:块* A *可能是与块* B *不同的内核。)

1 个答案:

答案 0 :(得分:5)

从CUDA C编程指南第5.3.2.2节,我们看到在几种情况下使用本地内存:

  • 当每个线程都有一些数组,但它们的大小在编译时是未知的(因此它们可能不适合寄存器)
  • 当在编译时知道数组的大小时,这个大小对于寄存器内存来说太大了(这也可能发生在大结构上)
  • 当内核已用完所有寄存器内存时(如果我们用n int填充了寄存器,n+1 int将会进入本地内存) - 最后一种情况是寄存器溢出,应该避免,因为:

"本地"内存实际上存在于全局内存空间中,这意味着与寄存器和共享内存相比,对它的读写速度相对较慢。每次在内核中使用一些不适合寄存器的变量,数组等时,您将访问本地内存,不是共享内存,并且没有作为全局内存传递。你不必做任何明确的事情来使用它 - 实际上你应该尽量减少它的使用,因为寄存器和共享内存要快得多。

编辑: Re:共享内存,你不能有两个块交换共享内存或看着对方'共享内存。由于无法保证块的执行顺序,如果您尝试这样做,可能需要将SMP占用几个小时,等待另一个块执行。同样,同时在设备上运行的两个内核无法看到彼此的内容。记忆,除非它是全球记忆,即便如此,你也要玩火(竞争条件)。据我所知,块/内核无法发送"消息"对彼此。你的场景确实没有意义,因为块的执行顺序每次都不同,并且阻止一个块等待另一个块是不好的做法。