Opengl 合并内存访问性能

Opengl 合并内存访问性能,opengl,cuda,gpu,gpgpu,Opengl,Cuda,Gpu,Gpgpu,我已经读过有关联合内存访问()及其性能重要性的内容。然而,我不知道当发生非合并内存访问时,典型的GPU会做什么。当一个线程“请求”位置P中的一个字节,而其他线程请求距离它很远的某个字节时,GPU会为该线程获得一个128字节的完整块?如果读数对齐,我是否可以读取“空闲”的其他127字节?一般规则: 内存访问指令与其他任何指令一样,都是以扭曲方式发出的 扭曲中的每个线程都提供一个可读取的地址 假设这些地址在任何缓存中都没有“命中”,内存控制器将收集所有地址并确定DRAM需要多少“段”(大致类似于缓

我已经读过有关联合内存访问()及其性能重要性的内容。然而,我不知道当发生非合并内存访问时,典型的GPU会做什么。当一个线程“请求”位置P中的一个字节,而其他线程请求距离它很远的某个字节时,GPU会为该线程获得一个128字节的完整块?如果读数对齐,我是否可以读取“空闲”的其他127字节?

一般规则:

  • 内存访问指令与其他任何指令一样,都是以扭曲方式发出的
  • 扭曲中的每个线程都提供一个可读取的地址
  • 假设这些地址在任何缓存中都没有“命中”,内存控制器将收集所有地址并确定DRAM需要多少“段”(大致类似于缓存线)。“段”是32字节或128字节,具体取决于缓存和设备规格
  • 然后,内存控制器从DRAM请求这些线/段
如果单个线程生成的地址不在warp中生成的任何其他地址附近,那么内存控制器将需要从DRAM请求一整行/段,这可能是32字节或128字节,具体取决于设备和涉及的缓存(即发生了什么类型的“未命中”)只是为了满足一个线程中的一个地址。因此,无论该线程在单线程读取事务中请求的是最小1字节还是最大16字节,内存控制器都必须从DRAM读取32字节或128字节,以满足来自该线程的读取。类似的逻辑将应用于该特定“扭曲读取”产生的所有其他地址

这种分散或隔离的访问模式是“未协调的”,因为warp中没有其他线程需要足够近的地址,以便它可以从同一段/线满足其需求

当一个线程“请求”位置p中的一个字节,而其他线程请求距离它很远的某个字节时,GPU会为该线程获得一个128字节的完整块

是的,32字节或128字节是可以从DRAM发出的请求的最小粒度

如果读数对齐,我是否可以读取其他127字节的“空闲”

无论您是否需要,也不管行/段内的请求是否对齐,都将从任何DRAM读取事务中获得32字节或128字节

这并不涵盖所有情况,但32字节/128字节差异的一般细分如下:

  • cc2.x设备具有启用的一级缓存,因此缓存“未命中”通常会触发128字节的读取
  • cc3.x设备仅启用二级缓存(用于全局内存事务),二级缓存线大小为32字节。这里的“未命中”需要从DRAM加载32字节的数据,但通过一个扭曲进行的完全合并读取最终仍需要加载128字节(例如,对于
    int
    float
    ),因此最终仍然需要四个二级缓存线。(没有免费的午餐。)
  • cc5.x设备再次启用了L1,因此在“未命中”情况下应恢复到需要完整的128字节加载

  • 这将是有益的。特别是,幻灯片17显示了一个“完美”合并的示例,而幻灯片25显示了一个“完全未校准”负载的示例。

    @Robert的答案非常准确。真正简短的回答是:非合并读取被序列化,内核只有在它们全部完成后才能继续。因此,您可以看到合并您的阅读的好处!比最坏的情况快32倍。