如何避免TLB丢失(和高全局内存重放开销)在CUDA gpu



标题可能比我的实际问题更具体,尽管我相信回答这个问题将解决一个更普遍的问题,即:如何减少来自gpu随机(但合并)全局内存访问的高延迟(~700个周期)的影响。

一般情况下,如果使用合并负载访问全局内存(例如:我读取128个连续字节),但是合并访问之间的距离非常大(256KB-64MB),就会得到很高的TLB (Translation Lookaside Buffer)失误率。如此高的TLB缺失率是由于TLB查找表中使用的内存页的数量(~512)和大小(~4KB)有限。

我认为高TLB失误率是因为NVIDIA使用虚拟内存的事实,我在分析器中获得高(98%)全局内存重放开销和低吞吐量(45GB/s,使用K20c)的事实,以及自费米以来分区野营不是问题的事实。

是否有可能以某种方式避免高TLB漏报率?如果我访问沿X维度合并的(X X Y X Z)立方体和沿Z维度的X*Y"跨步",3D纹理缓存会有帮助吗?

对这个话题的任何评论都是赞赏的。

约束:1)全局数据不能重新排序/转置;

您只能通过更改内存访问模式来避免TLB遗漏。内存中数据的不同布局可以帮助解决这个问题。
3D纹理并不能改善你的情况,因为它在两个额外维度上改善了空间局部性,而在第三个维度上减少了空间局部性。因此,您将不必要地沿着Y轴读取邻居的数据。

但是,您可以做的是减轻由此产生的延迟对吞吐量的影响。为了在全局内存带宽b = 250GB/s的情况下隐藏t = 700个周期的延迟,您需要为b/t = 175 KB的数据在任何时候进行内存事务处理(或为14个SMX中的每个SMX提供12.5 KB)。然而,在完全加载内存接口和高TLB失败率的情况下,您会发现延迟接近2000个周期,每sm大约需要32 KB的事务。

由于运行中的内存读事务的每个字都需要一个寄存器,一旦到达该值将存储在该寄存器中,因此隐藏内存延迟必须与寄存器压力相平衡。保持32kb的数据在飞行中需要8192个寄存器,或SMX上可用寄存器总数的12.5%。

(注意,对于上面的粗略估计,我忽略了KiB和KB之间的差异)。

最新更新