parallel-processing - 什么是 CUDA 11 中引入的 L2 缓存 accessPolicyWindow
问题描述
CUDA 11 中引入了新的运行时 API 来微调L2 访问策略。
但是我不完全理解策略之类的含义hitRatio
以及如何在实践中使用它们。
特别是,我在CUDA API 文档中看到cudaAccessPolicyWindow
:
指定窗口的访问策略,即从 base_ptr 开始到 base_ptr + num_bytes 结束的连续内存范围。划分为许多段并分配段这样。“命中段”/窗口的总和 == 约。比率。“未命中段”/窗口的总和 == 大约 1 比率。段和比率规范适合架构的功能。命中段中的访问应用 hitProp 访问策略。未命中段中的访问应用 missProp 访问策略。
我的问题:
内存的连续范围是如何“划分”成段的?这些分区是根据命中属性静态决定的,这样段的命中或未命中属性在分配后将保持不变,还是有一些运行中的计数器可以动态调整分配,例如在每个访问基础上?
在实践中应该如何应用这些属性来优化性能?例如,以一种过于简单和幼稚的方式来说,假设我留出了 1 MB L2 缓存,我应该为我最常用的数据创建一个 1 MB 的窗口并将 hitRatio 设置为 1 还是应该创建一个 2 的窗口MB 并将 hitRatio 设置为 0.5?为什么?
解决方案
内存的连续范围是如何“划分”成段的?这些分区是根据命中属性静态决定的,这样段的命中或未命中属性在分配后将保持不变,还是有一些运行中的计数器可以动态调整分配,例如在每个访问基础上?
我认为没有任何明确规定。然而,我们可以基于两个想法做出一些非常可靠的(我相信)猜想:
很长一段时间以来,NVIDIA GPU L2 缓存都具有 32 字节的基本行大小。这旨在与具有 32 字节段边界的 DRAM 子系统的设计保持一致。
该文档说明选择哪些行作为“随机”选择在缓存中持久存在。这几乎意味着它与访问模式无关。
结合这些想法,我会说分区是在不少于 L2 行(32 字节)的粒度上完成的,如果 L2 标签/TLB 系统需要,它可能是更高的粒度。这些 L2 细节中的大多数通常是 NVIDIA 未发布的。一旦随机选择,我不希望选择会根据访问模式而改变。
在实践中应该如何应用这些属性来优化性能?例如,以一种过于简单和幼稚的方式说,假设我留出了 1 MB L2 缓存,我应该为我最常用的数据创建一个 1 MB 的窗口并将 hitRatio 设置为 1 还是应该创建一个 2 的窗口MB 并将 hitRatio 设置为 0.5?为什么?
没有足够的信息来给出这个问题的具体答案。您决定保留 1MB L2 缓存的知识是第一个关键信息,但第二个关键信息是您实际上需要缓存多少数据?此外,预期的访问模式很重要。让我们介绍几种情况:
预留 1MB 缓存,1MB 窗口,hitRatio 1。这意味着您只有 1MB 的数据要使用此机制进行缓存。对于 1MB 缓存和 1MB 窗口,没有任何理由为 hitRatio 选择 1 以外的任何值。如果您只有 1MB 的数据要缓存,并且您有能力切出 1MB 的 L2,那么这是一个完全明智的选择。您实质上是在保证没有其他活动可以“驱逐”这些“受保护”数据,一旦它出现在缓存分割中。
预留 1MB 缓存,2MB 窗口,hitRatio 0.5。这当然意味着您至少有 2MB 的数据要使用此机制进行缓存,因此这与上述情况 1 无法直接比较。0.5的hitRatio可以被认为是防止抖动的“后卫”。让我们考虑几个子案例:
A. 假设您的 2MB 数据被分成 1MB 区域 A 和 B,并且您的代码访问区域 A 中的所有数据(一次),然后访问区域 B 中的所有数据(一次),然后访问区域 A 中的所有数据(一次) 等。如果您选择命中率为 1 并使用 1MB 缓存分割但有 2MB 窗口,则此设置将失败。您将用区域 A 填充缓存,然后用区域 B 逐出并填充,然后用区域 A 逐出并填充,等等。如果没有“hitRatio”机制/控制,这种情况下的这种行为将是不可避免的。因此,如果您预计这种循环访问模式,0.5 的命中率会更好(50% 的数据访问将受益于 L2 剥离,50% 不会)而不是完全没有从缓存中受益。
B. 假设您的 2MB 数据以高时间局部性访问。您的代码重复访问 2MB 数据中的 1MB(例如区域 A),然后重复访问另一个(区域 B)。在这种情况下,可能根本不需要拆分。如果您想使用分割,则命中率 1 可能是有意义的,因为这意味着该分割或多或少像普通缓存一样,除了可缓存窗口是用户定义的。在此示例中,您的缓存将填满您的前 1MB 区域 A 数据,然后您的代码将受益于缓存,因为它重用了该数据。当您的代码切换模式并开始使用第二个 1MB 数据(区域 B)时,第二个 1MB 将驱逐第一个 1MB,然后当您的代码重复使用第二个 1MB 时,它将再次从缓存中获得 100% 的收益。
推荐阅读
- json - AWS CloudFormation:“参数 [subnetIds] 无效”
- java - Spark SQL:窗口函数滞后直到满足条件
- arrays - 我是汇编语言编程的初学者,无法找出给定数组中的负数
- c# - 从水平轴和垂直轴获取角度
- reactjs - Reactjs 从子节点传递道具
- c - 我怎样才能让'C'中的这个回文程序重复五次?
- android - Android Studio:context.getFilesDir() 返回我找不到的路径 [/data/user/0/com.example.filesexperimenting/files/]。我错过了什么?
- wpf - 使用用户控件的 WPF 通知气球
- reactjs - withRouter 不能与 redux 一起正常工作 - react redux react-router
- node.js - 无法使 axios.put 从反应到 node.js 服务器