cuda - 将大小为 64 的数组存储在 Nvidia GPU 的寄存器中是否合适?
问题描述
为了演示这个问题,让我们考虑以下示例。假设我有两个数组A[16][64]
,B[16][N][64]
并且我想计算函数ans[i][j][N]=f(A[i], B[j][N])
在哪里。f
我将在一个块中编写一个包含 256 个线程的 cuda 内核,每个线程计算一对(i,j)
所有的ans[i][j][k]
s 。
最经典的方法将首先加载A
到共享内存中。但是,我发现由于A
将在一个线程中使用 N 次,加载到共享内存后,我可以进一步加载A[i]
到寄存器中以加快计算速度f(A[i], B[j][N])
。寄存器比共享内存快是常识。
我查了文档Compute Capability,发现每个线程最多可以有255个大于64的寄存器,所以使用64个寄存器是可以的。但我也听说过一个叫做寄存器压力的术语,它说使用许多寄存器可能会很慢。此外,我发现编译器经常限制寄存器的数量,如果寄存器的数量超过限制,就会使用本地内存。
基于以上事实,我有很多困惑。例如,在这种情况下我应该使用寄存器而不是共享内存吗?在这种情况下是否真的出现套准压力?访问寄存器比访问共享内存快多少?谢谢!
解决方案
....在这种情况下我应该使用寄存器而不是共享内存吗?
没有办法“使用”寄存器。编译器使用大量复杂的代码分析和启发式方法来确定寄存器的分配方式。程序员无法控制这一点。编译器会在它认为合适的时候溢出到本地内存。
在这种情况下是否真的出现套准压力?
没法说。显然,如果您增加内核的寄存器占用量,每个 SM 的最大线程数将在某个时候减少。是否影响性能是代码和设备特定的,是否需要基准测试数据。你没有提供这三件事的细节
访问寄存器比访问共享内存快多少?
几年前的一般规则(懒得查 Vasily Volkov 的分析)是寄存器带宽比共享内存高大约 10 倍
推荐阅读
- c# - Web 服务器上的 Crystal Reports 错误,但不是 localhost
- statistics - 关于流行病学计算的问题:辛普森悖论
- javascript - If/Else If 块未使用节点的“fs”模块激活
- android - 升级 gradle 后 Proguard 行为发生变化,从构建的 apk 中省略类
- r - 如何从最近一年R过滤到一年前
- javascript - 状态:400 标题:“发生一个或多个验证错误。”
- ansible - 正则表达式提取两个模式之间的线条
- php - Where did my errors go for PhpStorm (mac)
- c++ - ESP32 DevKitC Development on board LED blinking unintentionally
- google-cloud-functions - 为什么云功能每次都抛出错误