Caching 对GPU上全局内存位置的合并访问与广播访问

Caching 对GPU上全局内存位置的合并访问与广播访问,caching,cuda,gpu,kepler,Caching,Cuda,Gpu,Kepler,我有一个应用程序,我需要在全局内存中向所有线程广播一个(非常量,只是普通的旧数据)值。线程只需要读取值,而不需要写入。我无法明确告诉应用程序使用常量缓存(例如cudaMemcpyToSymbol),因为我使用的内存包装库不提供明确的低级控制 我想知道这个广播是如何在引擎盖下进行的,它与通常的访问模式有什么不同,在通常的访问模式中,每个线程访问一个唯一的全局内存位置(为了简单起见,假设这个“通常”的访问模式是合并的)。我特别感兴趣的是在广播情况下可能发生的任何隐式序列化,以及不同的体系结构如何影响

我有一个应用程序,我需要在全局内存中向所有线程广播一个(非常量,只是普通的旧数据)值。线程只需要读取值,而不需要写入。我无法明确告诉应用程序使用常量缓存(例如cudaMemcpyToSymbol),因为我使用的内存包装库不提供明确的低级控制

我想知道这个广播是如何在引擎盖下进行的,它与通常的访问模式有什么不同,在通常的访问模式中,每个线程访问一个唯一的全局内存位置(为了简单起见,假设这个“通常”的访问模式是合并的)。我特别感兴趣的是在广播情况下可能发生的任何隐式序列化,以及不同的体系结构如何影响这种序列化

例如,对于Fermi,第一个访问该值的线程可能会将其拉入二级缓存,然后拉入其SM的一级缓存,此时驻留在SM上的每个线程都会尝试从一级缓存中抓取该值。当所有线程尝试访问相同的一级缓存值时,是否存在序列化惩罚

对于开普勒,第一个访问该值的线程可能会将其拉入二级缓存(然后可能会或可能不会将其拉入一级缓存,具体取决于一级缓存是否启用)。当所有线程都试图访问L2中的相同值时,是否存在序列化惩罚

另外,分区露营是一个问题吗

我发现其中的另一个主题与此类似,但细节程度不足以满足我的好奇心

提前谢谢

我有一个应用程序,我需要在全局内存中向所有线程广播一个(非常量,只是普通的旧数据)值。线程只需要读取值,而不需要写入

另外,这几乎就是常量数据的定义,因为它与CUDA内核使用有关。您可能无法利用它,但这种访问称为“统一”访问,如果存在这种类型的重复访问,对于线程只读取而不写入的值,则可以考虑对内存进行优化

我想知道这个广播是如何在幕后进行的

明确地说,广播和/或序列化应该仅在同一扭曲中的线程访问特定数据项时才可能。当不同经纱中的螺纹访问同一位置时,这些术语不适用;这些将由单独的扭曲读取请求提供服务

当所有线程尝试访问相同的一级缓存值时,是否存在序列化惩罚

没有处罚。同一经纱中的线可以;从同一位置读取的所有线程将在同一个周期内进行服务(“广播”)。在费米上读取同一位置的单独扭曲中的线程将通过单独的读取请求提供服务,正如您对单独扭曲执行的任何指令所期望的那样。在这种情况下,也没有额外或不寻常的成本

当所有线程都试图访问L2中的相同值时,是否存在序列化惩罚

在这种情况下,上述L1适用于L2

另外,分区露营是一个问题吗


分区露营与从一级或二级缓存检索的值无关。分区露营通常是指一种数据访问模式,这种模式导致DRAM请求被具有多个内存分区的GPU上的一个分区不成比例地处理。对于由多个线程/扭曲读取的单个位置,缓存将为此提供服务。最多需要一个DRAM事务来处理所有在时间上彼此足够接近的请求(即忽略缓存抖动的可能性),以单个位置为目标。

嗨,Robert,非常感谢您的回复。如果可以的话,我会使用常量内存,但不幸的是,在这种情况下,它超出了我的控制范围。如果您愿意的话,这确实在我脑海中引起了另一个好奇点:假设每个SM在一级缓存中存储了相同的值。假设一个SM上的线程现在写入该值。根据,这将使L1中的相关缓存线无效,并写入L2中的相关缓存线。我的问题是:这是否也会使其他SMs保存在一级缓存中的值无效?它不会。因此,应避免使用此类编程范例,或者如果必须使用,则使用缓解策略,例如1.)使用
volatile
或2.)使用原子或3.)在本地或全局禁用L1缓存。当然还有其他的方法。