根据我所知,当warp的线程访问全局内存中的相同地址时,请求被序列化,因此最好使用常量内存。当GPU配备L1和L2缓存级别(在Fermi和Kepler架构中)时,是否会发生同步全局内存访问的序列化?换句话说,当warp的线程访问相同的全局内存地址时,warp的31个线程是否会从缓存中受益,因为1个线程已经请求了该地址?当访问是读取时以及访问是写入时会发生什么?
答案 0 :(得分:2)
Fermi和Kepler中同一个warp中的线程对同一地址的同时全局访问不会被序列化。 warp读取具有广播机制,该机制满足来自单个高速缓存行读取的所有这些读取而没有性能影响。性能与完全合并读取的性能相同。无论缓存特定情况如何都是如此,例如即使禁用L1缓存也是如此。
未指定同时写入的性能(AFAIK),但行为,同时写入始终被序列化,并且顺序未定义。
编辑回复以下其他问题:
- 即使warp中的所有线程都将相同的值写入同一个地址,它是否会被序列化?是否存在识别这种情况的写广播机制?
醇>
没有一种写广播机制可以查看所有同时写入以查看它们是否完全相同,然后根据它进行一些操作。正确答案是写入以未指定的顺序发生,并且性能特征未定义。显然,如果写入的所有值都相同,则可以确保最终位于该位置的值将是该值。但是,如果您正在询问写入活动是否折叠为单个周期还是需要多个周期才能完成,那么实际行为是未定义的(未记录的),实际上可能从一个体系结构到另一个体系结构不同(例如,cc1.x可以以执行所有写入的所有方式进行序列化,而cc2.x可以以一种写入“获胜”并且所有其他写入被丢弃的方式“序列化”,而不是消耗实际周期。)同样,性能未记录/未指定,但程序可观察行为已定义。
2您解释过这种广播机制,常量内存广播访问和全局内存广播访问之间的唯一区别是第一个可以将访问一直路由到全局内存,但后者有专用硬件,速度更快,对吗?
__constant__
内存使用常量缓存,这是一个基于每个SM的专用硬件,并在只读时尚。此硬件高速缓存在物理上和逻辑上与L1高速缓存(如果存在并启用)和L2高速缓存分离。对于Fermi及更高版本,两种机制都支持读取时的广播,对于常量缓存,这是首选的访问模式,因为常量缓存每个周期只能服务一次读取访问(即不支持warp读取的整个缓存行)。这两种机制都可能在缓存中“命中”(如果存在)或“未命中”并触发全局读取。在给定位置(或高速缓存行)的第一次读取时,其他高速缓存将具有所请求的数据,因此它将“未命中”并触发全局存储器读取以服务该访问。此后,在任何一种情况下,假设相关数据在此期间不被驱逐,后续读取将从缓存中提供服务。对于早期的cc1.x设备,常量内存缓存非常有价值,因为那些早期的设备没有L1缓存。对于Fermi以及使用常量缓存的主要原因是,如果可识别数据(即只读)和访问模式(每个warp的地址相同)可用,那么使用常量缓存将阻止这些读取通过L1并且可能驱逐其他数据。实际上,您正在增加可缓存的占用空间,而不仅仅是L1可以单独支持的内容。