【问题标题】:shared memory optimization confusion共享内存优化混乱
【发布时间】:2011-04-10 09:10:00
【问题描述】:

我在 cuda 中编写了一个应用程序,它在每个块中使用 1kb 的共享内存。 由于每个 SM 中只有 16kb 的共享内存,所以总共只能容纳 16 个块(我理解正确吗?),虽然一次只能安排 8 个,但现在如果某个块忙于做内存操作,所以其他块将被调度到 gpu 上,但是所有共享内存都被其他 16 个块使用,这些块已经在那里调度,所以 cuda 不会在同一个 sm 上调度更多块,除非之前分配的块完全完成?或者它将某些块的共享内存移动到全局内存,并在那里分配其他块(在这种情况下我们应该担心全局内存访问延迟吗?)

【问题讨论】:

    标签: cuda memory-optimization


    【解决方案1】:

    它不是那样工作的。在任何给定时刻,单个 SM 上计划运行的块数始终为以下各项中的最小值:

    1. 8 块
    2. 静态和动态分配的共享内存之和小于 16kb 或 48kb 的块数,具体取决于 GPU 架构和设置。还有共享内存页面大小限制,这意味着每个块分配会四舍五入到页面大小的下一个最大倍数
    3. 每个块寄存器使用的总和小于 8192/16384/32678 的块数,具体取决于体系结构。还有寄存器文件页面大小,这意味着每个块的分配会四舍五入到页面大小的下一个最大倍数。

    这就是它的全部内容。没有共享内存的“分页”来容纳更多块。 NVIDIA 生成了一个用于计算占用率的电子表格,该电子表格随工具包一起提供,可单独下载。您可以在它包含的公式中看到确切的规则。 CUDA 编程指南的第 4.2 节也讨论了它们。

    【讨论】:

    • 这是否意味着有时最好不要使用共享内存?因为会有更多的块并行运行?
    • 这真的取决于。共享内存要慢得多,寄存器和寄存器没有银行冲突,所以如果可能的话,最好使用寄存器而不是共享内存。共享内存的传统用途是允许在一个块内的线程之间重用数据,并且在前费米时代它非常有效。在 Fermi 中,共享内存的情况可能不那么引人注目。 L1 和 L2 缓存意味着您通常可以在不执行任何操作的情况下达到共享内存铸币厂产量的很大一部分,并且无需担心银行冲突或序列化影响。
    • 那么,如果某些块被安排在一个 SM 上,现在所有的 warp 都在等待内存操作完成,那么 cuda 是否会在同一个 SM 上安排其他块(什么是否会发生在已分配块的共享内存数据上?)还是会等到分配的块完成操作?
    • 硬件将始终调度尽可能多的块,然后在资源可用之前不再调度,以便可以调度更多块。如果 SM 上的每个活动 warp 都在等待内存事务或处于同步屏障,则 SM 将被停止。调度启发式算法的确切工作方式并未正式记录,但共识似乎是在 pre fermi 卡中,在 SM 上完成每个块之前不会调度新块,但在 fermi 上它比这更灵活。跨度>
    猜你喜欢
    • 1970-01-01
    • 2011-01-04
    • 2018-12-30
    • 1970-01-01
    • 2018-10-11
    • 2012-07-31
    • 1970-01-01
    • 2011-12-27
    • 1970-01-01
    相关资源
    最近更新 更多