CUDA 11中引入的L2缓存访问策略窗口是什么?

3
CUDA 11引入了新的运行时API,以微调L2访问策略。
但我不完全理解像`hitRatio`这样的策略的含义,以及它们在实践中如何使用。
特别是,在CUDA API文档中我看到了`cudaAccessPolicyWindow`:
指定窗口的访问策略,该窗口是从base_ptr开始并以base_ptr + num_bytes结束的连续内存范围。将其分成许多段并分配段,使得"命中段"的总和/窗口≈比率,"未命中段"的总和/窗口≈1-比率。段和比例规格适合架构的功能。命中段中的访问采用hitProp访问策略。未命中段中的访问采用missProp访问策略。
我的问题是:
内存的连续区域是如何被“分割”成段的?这些分段是基于命中属性静态决定的,使得一旦它们被分配,它们的命中或未命中属性将保持不变,还是有一些运行计数器动态调整分配,例如在每次访问时基础上?
在实践中,应该如何应用这些属性以优化性能?例如,假设我有1 MB的L2缓存,我应该为我的最常用数据创建一个1 MB的窗口,并将命中率设置为1,还是应该创建一个2 MB的窗口,并将命中率设置为0.5?为什么?

3
我不是在建议这篇文章可以回答你所有的问题,但是这可能会引起你的兴趣,特别是其中的"内存管理"章节。此外,在这里的幻灯片22-26页也许对你有帮助。链接见上述英文内容。 - undefined
1个回答

3
如何将连续的内存范围“分区”为片段?这些分区是基于命中属性静态决定的,因此一旦它们被分配,片段的命中或未命中属性将保持不变,还是有一些运行计数器动态调整分配,例如每次访问都会调整?
我认为这些都没有明确规定。然而,我们可以根据两个想法做出一些相当坚实的推测:
1. NVIDIA GPU L2缓存已经有32字节的基本行大小很长时间了。这是为了与DRAM子系统的32字节段边界设计对齐。
2. 文档指出,选择哪些行在缓存中保持持久性是“随机”的选择。这几乎意味着它与访问模式无关。
将以下文本翻译成中文:

然后,我会说分区的粒度至少为L2线(32字节),如果需要L2标记/TLB系统,则可能是更高的粒度。 NVIDIA通常不公开大多数这些L2细节。 一旦随机选择,我不希望根据访问模式更改选择。

在实践中如何应用这些属性以优化性能?例如,过于简单和幼稚地说,如果我设置了1 MB L2缓存,是否应该为我的最常用数据创建1 MB的窗口并将hitRatio设置为1,还是应该创建2 MB的窗口,并将hitRatio设置为0.5?为什么?

没有足够的信息来回答这个问题。您决定设置1MB L2缓存是第一个关键信息,但第二个关键信息是您实际上要缓存多少数据?此外,预期的访问模式也很重要。让我们涵盖几种情况:

1MB的缓存被保留,1MB的窗口,命中率为1。这意味着您只有1MB的数据想要使用此机制进行缓存。使用1MB的缓存和1MB的窗口,没有理由选择除1以外的其他命中率。如果您只有1MB的数据需要缓存,并且您可以承担削减1MB的L2的代价,那么这是一个完全合理的选择。您基本上保证了一旦它出现在缓存划分中,没有其他活动可以“驱逐”这个“受保护”的数据。
1MB的缓存被保留,2MB的窗口,命中率为0.5。当然,这意味着您至少有2MB的数据想要使用此机制进行缓存,因此这与上面的第1种情况不可直接比较。命中率为0.5可以看作是防止抖动的“保护”。让我们考虑几种子情况:
A. 假设您的2MB数据被分成1MB的区域A和B,您的代码先访问所有区域A的数据(一次),然后访问所有区域B的数据(一次),然后再访问所有区域A的数据(一次),等等。如果您选择了一个命中率为1,1MB缓存划分但2MB窗口的设置将会出现抖动。您会用区域A填充缓存,然后驱逐并用区域B填充,然后再驱逐并用区域A填充,等等。如果没有“命中率”机制/控制,这种情况下的这种行为是不可避免的。因此,如果您预计这种循环访问模式,那么0.5的命中率会更好(50%的数据访问将从L2划分中受益,50%则不会),而不是根本没有从缓存中受益。
B. 假设您的2MB数据具有高时间局部性。您的代码反复访问其中1MB(比如区域A)的2MB数据,然后反复访问另一个(区域B)。在这种情况下,可能根本不需要进行划分。如果您想要使用划分,则命中率为1可能是有意义的,因为它意味着此划分的行为基本上类似于普通缓存,唯一的例外是可缓存窗口是用户定义的。在此示例中,您的缓存将填满第一个1MB的区域A数据,然后当您的代码重复使用该数据时,代码将从缓存中受益。当您的代码切换模态并开始使用第二个1MB的数据(区域B)时,这第二个1MB将驱逐第一个1MB,然后当您的代码重复使用第二个1MB时,它将再次从缓存中受益。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接