在我的CUDA应用程序中,我正在从设备内存复制数据到共享内存。这些数据也会缓存在L1吗?
默认情况下,全局内存中的所有内存读取都会被缓存在L1中。全局内存加载的目标位置对L1缓存没有影响(无论是寄存器、共享内存还是线程本地内存)。共享内存本身显然不会被缓存。
这只是为了对@talonmies所说的进行扩展。
在低级别上,复制是两个单独的操作,即一个加载和一个存储。如果它们访问全局内存,则加载和存储都可以在L1和L2中缓存。
由于你的复制的加载部分来自全局内存,所以默认情况下它将在L1和L2中都被缓存。因此,除非编译器检测到从全局到共享内存复制的特殊情况并使用未缓存加载,否则你将得到两个数据副本,可以在相同延迟下访问,因为共享内存和L1高速缓存都是使用相同的芯片上物理内存实现的。
来自CUDA C编程指南4.2:
每个多处理器都有一个L1高速缓存,所有多处理器共享一个L2高速缓存,二者都用于缓存对本地或全局内存的访问,包括临时寄存器溢出。缓存行为(例如读取是否在L1和L2中都被缓存或仅在L2中被缓存)可以通过修改load或store指令的修饰符在每次访问时进行部分配置。
我找不到有关如何从CUDA C修改此行为的任何信息。
自CUDA 11以来,有使用缓存提示加载函数(也可以存储)。因此,可以使用例如__ldcg()
来避免在L1中进行缓存。以前,这些缓存提示已经通过内联PTX汇编可用。
请注意,如果同一SM上驻留的不同块访问的全局内存位置存在重叠,则L1缓存仍可能有益。由于L1缓存行粒度,重叠甚至可能是偶然的。
-Xptxas="-dlcm=cg"
将强制汇编程序生成32字节而不是128字节的事务,从而绕过L1缓存。 - talonmies