物理上连续的大内存区域



对于我的 M.Sc 论文,我必须对英特尔在其CPU内部使用的哈希函数进行逆向工程,以便在Sandy Bridge和新一代的最后一级缓存切片之间传播数据。为此,我正在 Linux 中开发一个应用程序,它需要一个物理上连续的内存区域才能进行测试。这个想法是从这个区域读取数据,以便缓存它们,探测旧数据是否已被逐出(通过延迟措施或LLC未命中计数器),以便找到冲突的内存地址,最后通过比较这些冲突地址来发现哈希函数。研究人员已经在Windows中使用了相同的过程,并被证明是有效的。

为此,我需要分配一个必须很大(64 MB 或更大)且完全可缓存的区域,因此 TLB 中没有 DMA 友好的选项。如何执行此分配?

为了完全控制分配(即,让它在物理上真正连续),我的想法是编写一个 Linux 模块,导出一个设备并从用户空间中 mmap() 它,但我不知道如何在内核内分配这么多连续内存。我听说过Linux连续内存分配器(CMA),但我不知道它是如何工作的。

应用程序看不到物理内存,进程在虚拟内存中具有一些地址空间。阅读有关 MMU 的信息(虚拟空间中连续的东西可能实际上不是物理连续的,反之亦然)

您可能希望使用 mlock(2) 锁定一些内存

但是您的应用程序将被调度,其他进程(或计划任务)会弄脏您的 CPU 缓存。参见sched_setaffinity(2)

(甚至内核代码也可能被抢占)

这个关于内核新手的页面,有一些关于内存分配的想法。但get_free_pages的最大尺寸看起来像8MiB。(也许这是一个编译时约束?

由于这将是全自定义的,因此您可以探索 linux 内核的 mem= boot 参数。这将限制使用的内存量,您可以在没有人知道的情况下在剩余内存上聚会。哎呀,如果你启动一个 busybox 系统,你可能会做mem=32M,但如果你不启动 GUI,即使是mem=256M也应该可以工作。

您还需要查看脱机调度程序(和此处)。它从Linux上"拔下"CPU,因此您可以完全控制在其上运行的所有代码。(其中的某些部分已经在主线内核中,也许全部都在主线内核中。

最新更新