繁体   English   中英

使物理地址区中的虚拟地址连续如何提高性能?

[英]How does making the virtual address contiguous in physical address zone improve performance?

最近我在 dpdk(dpdk.org) 中阅读有关大页面的代码。 我看到代码故意使虚拟地址在物理地址区域中连续。 具体来说,它首先检查巨页中是否存在物理连续区域,并将物理连续区域映射到连续的虚拟地址。 这如何提高性能?

源代码说:

为了保留大量的连续内存,我们使用了linux的hugepage特性。 为此,我们需要安装 Hugetlbfs。 此代码将在此目录中创建许多文件(每页一个)并将它们映射到虚拟内存中。 对于每个页面,我们将检索其物理地址并重新映射它,以便具有虚拟连续区域和物理连续区域。

为什么需要重新映射?

将物理上连续的区域映射到连续的虚拟地址。 这如何提高性能?

DPDK 需要物理地址和虚拟地址。 虚拟地址通常用于加载/存储一些数据。 物理地址对于用户空间驱动程序向/从设备传输数据是必需的。

例如,我们分配了几个mbuf s的虚拟地址0x410000x420000x43000 然后我们用一些数据填充它们并将这些虚拟地址传递给 PMD 进行传输。

驱动程序必须将这些虚拟地址转换为物理地址。 如果物理页面被映射到不连续的虚拟地址空间,为了将虚拟地址转换为物理地址,我们需要搜索所有映射。 例如,虚拟地址0x41000可能对应于物理0x810000x42000对应于0x16000 ,和0x43000 -到0x64000

这种搜索的最佳情况是读取一次内存,最坏的情况是每个缓冲区读取几次内存

但是如果我们确定一个内存区域的虚拟地址和物理地址都是连续的,我们只需向虚拟地址添加一个偏移量即可获得物理地址,反之亦然。 例如,虚拟0x41000对应于0x81000 ,虚拟0x42000到物理0x82000 ,和0x43000 - 0x83000

我们从映射中知道的偏移量。 这种转换的最坏情况是突发中每个缓冲区读取一个内存,这对转换来说是一个巨大的改进。

为什么需要重新映射?

为了将大页面映射到虚拟地址空间,使用了mmap系统调用。 调用的 API 允许为要映射的大页面指定固定的虚拟地址。 这允许一个接一个地映射大页面,创建一个连续的虚拟内存区域 例如,我们可以在虚拟地址0x200000mmap一个大页面,在虚拟地址0x4000000x200000下一个大页面,依此类推。

不幸的是,我们不知道大页面的物理地址,直到它们被映射。 因此,在虚拟地址0x200000我们可能会映射物理地址0x800000 ,而在虚拟地址0x400000 ——物理地址0x600000

但是一旦我们第一次映射这些大页面,我们就会知道物理地址和虚拟地址。 所以我们需要做的就是以正确的顺序重新映射它们:在虚拟地址0x1200000我们映射物理地址0x600000 ,在0x1400000 — 物理地址0x800000

现在我们有一个虚拟和物理连续的内存区域,从虚拟地址0x1200000和物理地址0x600000 因此,要将这个内存区域中的虚拟地址转换为物理地址,我们只需要如前所述从虚拟地址中减去偏移量0x600000

希望这可以澄清连续内存区域和重新映射的想法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM