2

我有一个内核,它使用大量寄存器并将它们大量溢出到本地内存中。

    4688 bytes stack frame, 4688 bytes spill stores, 11068 bytes spill loads
ptxas info    : Used 255 registers, 348 bytes cmem[0], 56 bytes cmem[2]

由于溢出似乎相当高,我相信它可以通过 L1 甚至 L2 缓存。由于本地内存对每个线程都是私有的,编译器如何合并对本地内存的访问?该内存是否像全局内存一样以 128 字节事务读取?有了这么多的溢出,我的内存带宽利用率很低(50%)。我有类似的内核,没有溢出,可以获得高达 80% 的峰值内存带宽。

编辑我使用该nvprof工具提取了更多指标。如果我很好地理解了这里提到的技术,那么由于寄存器溢出(4 * l1 命中和未命中 / L2 = 的 4 个扇区的所有写入总和),我会产生大量内存流量(4 * (45936 + 4278911)) / (5425005 + 5430832 + 5442361 + 5429185) = 79.6%。有人可以验证我是否在这里吗?

Invocations                                Event Name         Min         Max         Avg
Device "Tesla K40c (0)"
Kernel: mulgg(double const *, double*, int, int, int)
     30        l2_subp0_total_read_sector_queries     5419871     5429821     5425005
     30        l2_subp1_total_read_sector_queries     5426715     5435344     5430832
     30        l2_subp2_total_read_sector_queries     5438339     5446012     5442361
     30        l2_subp3_total_read_sector_queries     5425556     5434009     5429185
     30       l2_subp0_total_write_sector_queries     2748989     2749159     2749093
     30       l2_subp1_total_write_sector_queries     2748424     2748562     2748487
     30       l2_subp2_total_write_sector_queries     2750131     2750287     2750205
     30       l2_subp3_total_write_sector_queries     2749187     2749389     2749278
     30                         l1_local_load_hit       45718       46097       45936
     30                        l1_local_load_miss     4278748     4279071     4278911
     30                        l1_local_store_hit           0           1           0
     30                       l1_local_store_miss     1830664     1830664     1830664

编辑

我意识到这是 128 字节,而不是我想的位事务。

4

1 回答 1

3

根据 本地内存和 寄存器溢出,寄存器溢出对性能的影响不仅仅是在编译时决定的合并;更重要的是:从/向二级缓存读取/写入已经非常昂贵,您想避免它。

该演示文稿建议使用分析器在运行时计算由于本地内存 (LMEM) 访问而导致的 L2 查询数量,查看它们是否对所有 L2 查询的总数产生重大影响,然后优化共享与 L1 的比率支持后者,通过单个主机调用,例如 cudaDeviceSetCacheConfig( cudaFuncCachePreferL1 );

希望这可以帮助。

于 2014-05-26T21:47:23.973 回答