针对这个问题的一项技术回应是引入Compute Express Link™, or CXL, 它允许内存池在多个计算节点之间连接和共享,并使内存可伸缩性优于本地DRAM的数量级. 它还需要基于性能和局部性对内存进行粒度分层, 从处理器缓存和GPU本地内存(高带宽内存(HBM))到具有更深奥的相干结构的慢得多的远内存.
Generally, this expansion of memory capacity is only related to DRAM + CXL; storage is largely unaffected and the operation of NVMe SSDs shouldn’t be impacted, right?
Not exactly. ssd应该知道分层内存,并且可以进行优化以提高性能, latencies, or both, 对于高性能工作负载. 这个用例的一个SSD优化需要ATS及其相关的ATC的支持,我们将在这里讨论.
What is ATS/ATC?
ATS/ATC最相关的用途是在虚拟化系统中. 它们也可以在非虚拟化系统中使用, 但是一个简单的描述详细说明了ATS/ATC如何通过跟踪直接分配虚拟化系统中虚拟机(VM)的数据路径来工作, 使用标准技术,如SrIOV. 参考图表如下:
![](http://media-2q.bodegapuenteajuda.com/-/media/client/global/images/blogs/content-images/2023/october/ats-blog/ats1.png?h=568&w=415&la=en&rev=887c412557b641ebaac1d2f47d9badfb&hash=98F05992A9BB5560C8E15783EE31E647)
Figure 1 ATS/ATC path
虚拟化的一个关键租户是,来宾虚拟机不知道它正在虚拟化环境中运行. 系统设备(如ssd)认为它们正在与单个主机通信,而不是与过多的vm通信, 因此,它们可以正常工作,而不需要在SSD上附加逻辑
这种方法的一个后果是内存寻址. 客户操作系统被设计为在专用系统上运行, so it thinks it is using system memory addresses (SVA = system virtual address; SPA = system physical address) but in reality, 它运行在一个VM空间中,由管理程序管理, 提供虚拟机本地的客户地址,但与系统地址映射完全不同. 客户操作系统认为它正在使用SVA和SPA, 但它实际上是使用客户虚拟地址(GVA)和客户物理地址(GPA)
在从本地(来宾)寻址方案到全局(系统)寻址方案的转换过程中必须小心. 处理器中有两种转换机制:内存管理单元(MMU)支持程序直接寻址的内存(与SSD无关),IOMMU支持所有DMA传输的转换, 哪个是最关键的.
As seen in Figure 1, 每次虚拟机中的客户操作系统想要从SSD执行读取操作时, 它必须提供DMA地址. 它提供的是它认为是SPA,但实际上是GPA. 作为DMA地址发送到SSD的只是GPA吗. 当SSD盘发出请求的数据时, 它发送PCIe数据包(称为事务层数据包[TLPs]), (通常高达512B的大小),它知道的GPA. In this case, IOMMU查看传入地址, understands it is a GPA, 查看其转换表以确定相应的SPA是什么, 并将GPA替换为SPA,以便可以使用正确的内存地址.
为什么我们关心NVMe的ATS/ATC?
如果系统中有许多ssd或CXL设备,可能会导致地址转换的风暴,从而阻塞IOMMU, 导致系统瓶颈.
例如,现代SSD可以执行高达600万IOPS,每个4KB. 假设TLP = 512B,每个IO被分成8个TLP,因此有4800万个TLP需要翻译. 假设IOMMU每4个设备实例化一次,它每秒转换1.92亿TLP. 这是一个很大的数字,但情况可能会更糟,因为tlp“最高可达512B”,但也可能更小. 如果TLPs越小,翻译量就越高.
我们需要找到一种减少翻译次数的方法. 这就是ATS的意义所在:一种提前请求翻译并在有效期内重用翻译的机制. Given the OS page is 4KB, 每次翻译使用8个TLP, 按比例减少翻译的数量. 但是在大多数虚拟化系统中,页面可以是连续的, 下一个有效粒度是2MB, 因此每次翻译可用于8*2M/4K = 4096个连续TLP(如果使用小于512B的TLP,则可以使用更多). 这使得IOMMU必须提供的翻译数量从200万降到100万以下, 这样就减轻了堵塞的风险.
NVMe的ATS/ATC建模
In NVMe, 提交和完成队列(SQ和CQ)的地址对每个命令各使用一次. 我们不应该保留这样的(静态)翻译的副本吗? Absolutely. 这正是ATC所做的:保存最常见翻译的缓存副本.
这里的主要问题是SSD会接收什么样的DMA地址模式,以便ATS/ ATC可以围绕它们进行设计? 不幸的是,没有相关的数据或文献.
我们通过构建一个工具来解决这个问题,该工具可以跟踪SSD接收到的所有地址并存储它们,以便将它们用于建模目的. To be significant, 数据需要来自实际应用程序的一些可接受的表示形式,具有足够的数据点来表示我们缓存实现的有效数据集.
我们为一系列数据中心应用程序选择了通用的工作负载基准, ran them, 并进行了每段20分钟的IO跟踪. 这导致每个跟踪产生数亿个数据点,为建模工作提供数据.
收集到的数据示例如下图所示, 通过使用XFS文件系统在RocksDB上运行YCSB (Yahoo Cloud Server Benchmark)来执行:
存储数据ATC评估:
- Characterization Method:
- 假设虚拟机运行标准工作负载.
- 跟踪每个工作负载的唯一缓冲区地址
- 将它们映射到STU (2mb)较低的页面
- 构建ATC的Python模型
- 重放跟踪到模型以验证命中率
- 对尽可能多的工作负载和配置进行重复
![](http://media-2q.bodegapuenteajuda.com/-/media/client/global/images/blogs/content-images/2023/october/ats-blog/ats2.png?la=en&rev=90e33523f3794992a95b12959f3c7173&hash=C79DDA333611E71134926D88FDD03D0C)
观察结果:多虚拟机, as expected, 具有比单个图像更少的局部性,但缩放不是线性的(4倍大小的16倍#VM)
计算缓存需求, 我们构建了一个缓存的Python模型,并重播了整个跟踪(所有数亿个条目),并分析了缓存行为. 这使我们能够对缓存大小(行数)的变化进行建模。, eviction policies, STU sizes, 以及其他与建模相关的参数.
我们对每个基准测试分析了1.5亿到3.7亿个数据点,发现使用的唯一地址通常以数万个为单位, 对于缓存大小来说,这是一个很好的结果. 如果我们进一步将它们映射到最常用的2MB页面上
最小的传输单元(STU),页数减少到几百或几千.
这表明缓冲区的重用非常高, 这意味着即使系统内存在TB范围内, IOs使用的数据缓冲区数量在GB范围内,使用的地址数量在数千个范围内, 使其成为缓存的一个很好的候选.
我们担心高地址重用是由于我们特定系统配置中的局部性, 因此,我们针对几个不同的数据应用程序基准运行了额外的测试. 下表将上述YCSB/RocksDB/XFS测试之一与Microsoft SQL Server上使用XFS的TPC-H进行比较, 一个完全不同的基准:
Correlation with TPC-H:
- IO分布非常不同:
- 3.2倍的唯一地址…
- … but distributed in 70% of STU -> Higher locality
- 缓存命中率收敛在64项左右,与RocksDB一致
![](http://media-2q.bodegapuenteajuda.com/-/media/client/global/images/blogs/content-images/2023/october/ats-blog/ats3.png?h=507&w=1464&la=en&rev=f5b94d8f125548afb779f5a900e34867&hash=F622D705A6234C08A397983C2FA532F4)
数据跟踪完全不同,但如果缓存大小足够大(比如64行),它们会收敛到相同的命中率.
类似的发现已经在其他几个基准测试中得到验证,为了简短起见,这里没有报告.
Size dependency:
- 基准使用:YCSB WL B与卡桑德拉
- Cache: 4路Set Associative
- Algorithm: Round Robin
- Observations:
- 正如预期的那样,命中率高度依赖于STU的大小
- STU大小越大,命中率越高
- 并非所有数据都是平等创建的:每个NVMe命令都需要访问SQ和CQ,因此这些地址对命中率有巨大的影响
![](http://media-2q.bodegapuenteajuda.com/-/media/client/global/images/blogs/content-images/2023/october/ats-blog/atsgraph1.png?la=en&rev=f6f363152bc64aff8fb450af27034074&hash=6CCBAC9208348BEE982D54D395CAB0D2)
建模、数据固定和删除算法
我们还可以对不同算法对特殊数据固定(提交队列和完成队列)和数据替换的影响进行建模. 结果如下两张图所示:
第一组图验证了两行大小对缓存的依赖关系, STU尺寸以及是否将SQ和CQ固定到ATC会产生任何差异. 对于相对较小的缓存,答案显然是肯定的, 因为这两组曲线在形状上非常相似,但SQ/CQ缓存的曲线在小缓存下的命中率要高得多. For example, 在STU = 2MB并且只有1条缓存线时(在实践中非常不可能,但有助于说明这一点),没有任何SQ/CQ缓存的命中率低于10%,但是SQ/CQ固定的命中率接近70%. 因此,这是一个值得遵循的良好实践.
至于缓存的敏感性,所选择的清除算法, 我们测试了最近最少使用(LRU), 轮询(RR)和随机(Rand). 如下所示,其影响几乎可以忽略不计. 因此,应该选择最简单、最有效的算法.
Algorithms dependency:
- Benchmark used:
- YCSB WL B with Cassandra
- 一个更大的集合的一部分
- 结合性:全和四种方式
- 驱逐算法:LRU, Rand和Round Robin
- Outcome:
- 替换算法不会产生任何明显的差异
- 选择最简单的实现可能是最有效的方法
![](http://media-2q.bodegapuenteajuda.com/-/media/client/global/images/blogs/content-images/2023/october/ats-blog/ats6.png?la=en&rev=14cbde64938f4bc1bf9b0a9eb7ac870d&hash=FA1C012232B384DCAC755C085ED527C5)
Conclusion
那么,我们能用这个做什么呢? 这种方法的缺陷是什么?
这证明了围绕测量参数定量设计ATC缓存的途径,从而可以适当调整性能和设计影响.
对我们方法的一些警告:本报告代表了我们的初步分析,并非结论性的. For example, 从ATS/ATC中获益最大的应用程序是在虚拟化环境中, 但这些痕迹不是来自这样的设置. 数据显示了如何弥合这一差距,但这种方法更多的是理论上的,而不是可用的, 每个ASIC设计都应该考虑适当的权衡. 另一个需要弥补的差距是,ASIC设计需要近3年的时间,新沙巴体育结算平台可以再使用2-3年,并且具有多年的使用寿命. 预测3-7年后的工作量会是什么样子是很有挑战性的. 有多少虚拟机将在多少核心上运行,我们将使用多少内存?
In our testing, 我们已经找到了一条通往定量解决和未知的道路, scary as they may seem, 在建模世界中并不罕见,需要通过任何新的ASIC设计来解决.