我有一个使用大量寄存器的内核,并将它们大量溢出到本地内存中。
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缓存。由于本地内存对每个线程都是私有的,因此如何访问由编译器合并的本地内存?这个内存是在128byte事务中读取的,比如全局内存吗?有了这么多的溢出,我的内存带宽利用率就会降低(50%)。我有类似的内核,没有溢出,可以获得高达80%的峰值内存带宽。
EDIT
我使用nvprof
工具提取了更多指标。如果我很好地理解提到here的技术,那么由于寄存器溢出,我有大量的内存流量(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字节而不是我想到的位事务。
答案 0 :(得分:3)
根据 Local Memory and Register Spilling 注册溢出对性能的影响不仅仅需要在编译时决定合并;更重要的是:从/向L2缓存读/写已经相当昂贵,你想避免它。
该演示文稿建议使用分析器,您可以在运行时计算由于本地内存(LMEM)访问导致的L2查询数,查看它们是否对所有L2查询的总数产生重大影响,然后优化共享例如,通过单个主机呼叫,以L1比率支持后者 cudaDeviceSetCacheConfig(cudaFuncCachePreferL1);
希望这有帮助。