Cuda 本地、全球、固定和;共享内存

Cuda 本地、全球、固定和;共享内存,cuda,gpu-shared-memory,gpu-constant-memory,gpu-local-memory,Cuda,Gpu Shared Memory,Gpu Constant Memory,Gpu Local Memory,我读了一些CUDA文档,其中提到了本地内存。(这主要是早期的文档。)设备属性报告本地mem大小(每个线程)。“本地”内存是什么意思?什么是“本地”内存?“本地”内存在哪里?如何访问“本地”成员?它是\uuuu设备\uuuuu内存,不是吗 设备属性还报告:全局、共享和常量内存大小。 这些说法是否正确: 全局内存是设备内存。它具有网格作用域和网格(内核)的生命周期。 常量内存是\uuuuuu设备\uuuuuu常量内存。它具有网格范围&网格(内核)的生命周期。 共享内存是设备共享内存。它具有单个块作用

我读了一些CUDA文档,其中提到了本地内存。(这主要是早期的文档。)设备属性报告本地mem大小(每个线程)。“本地”内存是什么意思?什么是“本地”内存?“本地”内存在哪里?如何访问“本地”成员?它是
\uuuu设备\uuuuu
内存,不是吗

设备属性还报告:全局、共享和常量内存大小。 这些说法是否正确: 全局内存是
设备
内存。它具有网格作用域和网格(内核)的生命周期。 常量内存是
\uuuuuu设备\uuuuuu常量
内存。它具有网格范围&网格(内核)的生命周期。 共享内存是
设备共享
内存。它具有单个块作用域&该块(线程)的生存期

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

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

  • 当每个线程都有一些数组,但它们的大小在编译时未知时(因此它们可能不适合寄存器)
  • 当数组的大小在编译时已知,并且这个大小对于寄存器内存来说太大时(对于大结构也可能发生这种情况)
  • 当内核已经用完所有寄存器内存时(因此,如果我们用
    n
    int
    s填充寄存器,则
    n+1
    th
    int
    将进入本地内存)-最后一种情况是寄存器溢出,应该避免,因为:
“本地”内存实际上存在于全局内存空间中,这意味着与寄存器和共享内存相比,对它的读写速度相对较慢。每次在内核中使用一些变量、数组等时,您都会访问本地内存,这些变量、数组等不适合寄存器,不是共享内存,也不是作为全局内存传递的。您不必做任何显式的操作来使用它——事实上,您应该尽量减少它的使用,因为寄存器和共享内存要快得多

编辑: Re:共享内存,您不能让两个块交换共享内存或查看彼此的共享内存。由于无法保证块的执行顺序,如果您尝试这样做,可能会占用SMP数小时,等待另一个块执行。类似地,设备上同时运行的两个内核不能看到彼此的内存,除非它是全局内存,即使这样,你也在玩火(竞争条件)。据我所知,块/内核不能真正相互发送“消息”。您的场景并没有真正意义,因为块的执行顺序每次都会不同,并且让一个块等待另一个块是不好的做法

“本地内存”中的“本地”表示“线程本地”,即每个线程在自己的实例上运行。您是正确的,这只是从一般设备内存中分割出来的内存。相反,共享内存可供同一线程块中的所有线程访问,也就是说,它由线程块中的线程共享。全局内存可由整个网格中的任何线程访问,但如果不同线程希望访问同一位置(例如通过使用原子操作),则必须小心。