在 gem5 中对链接器进行基准测试


tl;dr:构建 gem5 时使用 mold 链接器 以获得最快的链接时间

熟悉 gem5 的人都知道它的编译时间很长,尤其是在链接阶段。 当即使是微小的编辑也需要重新链接先前编译的文件时,这可能会变得令人沮丧。 这可能会增加几分钟的过程。 考虑到这一点,我们评估了一系列 gem5 当前支持的链接器,以确定哪一个最有效。

为了进行这些测试,我们仔细检查了 gem5 当前支持的每个链接器,包括当前默认链接器 “ld”。 评估的四个额外支持的链接器是 “lld”、”bfd”、”gold” 和 “mold”。

我们比较这些链接器的方法如下:我们首先通过执行 scons build/ALL/gem5.opt 正常构建 gem5。 一旦 gem5.opt 二进制文件被编译,我们删除它。 因此我们留下了编译的目标文件但没有链接的二进制文件。 然后,我们使用 /usr/bin/time scons build/ALL/gem5.opt -j12 --linker=[linker-option] 比较使用每个链接器重建/链接 gem5 的运行,其中 /usr/bin/time 测量持续时间。 我们在使用 AMD EPYC 7402P 24 核处理器(频率为 3.35 GHz)的系统上运行这些测试。

在这些测试期间,我们观察到在我们的实验设置中使用除默认 “ld” 之外的链接器强制重新编译所有 m5 文件。 但是,如果我们在之后删除 gem5.opt 二进制文件并再次运行编译,只有 gem5.opt 被重建/链接,导致两个不同的时间。 为了比较时间,我们需要考虑第一次运行构建所有 m5 文件所需的时间,以及第二次运行重新链接 gem5.opt 所需的时间。 这些在下面标记为 “all m5” 与 “last few”。 除了这两次运行之外,我们还在网络文件系统 (NFS) 和本地 SSD 上比较了每次运行,以查看文件的存储类型是否对运行时间有任何影响。 最后,我们在本地 SSD 上使用系统上的 48 个可用核心执行了最后一次运行,以评估是否有所不同。 下面,我们展示了每次运行的经过时间。

我们发现,在我们测试的四个链接器中,”bfd” 最慢,”mold” 最快。 此外,使用 -j12-j48 之间的差异似乎微不足道。

根据我们的结果,我们建议在使用 gem5 时使用 “mold” 作为链接器。 值得注意的是,使用特定链接器对所用时间的影响比存储位置更显著。

  NFS + all m5 NFS + last few Local SSD + all m5 Local SSD + last few Local SSD + -j48 + last few
ld 3:29.19 3:08.31 3:00.15
bfd 4:15.82 3:32.13 3:39.70 3:02.15 3:02.35
lld 2:16.22 1:54.25 1:52.94 1:13.12 1:13.16
gold 2:30.98 1:43.59 1:59.41 1:19.86 1:19.48
mold 1:48.62 1:07.08 1:08.18 0:28.23 0:27.89

除了仅比较构建时间之外,我们还为每个链接的编译执行了 100000000 个 tick,以确保使用这些链接器在实际使用 gem5 时不会引起任何问题,例如增加执行时间或功能问题。

我们通过使用 O3 CPU 和 Ruby 缓存执行 x86 linux 启动来实现这一点。执行此操作的命令如下所示。

命令:

/usr/bin/time build/ALL/gem5.opt -re tests/gem5/configs/x86_boot_exit_run.py --cpu o3 --num-cpus 2 --mem-system mesi_two_level --dram-class DualChannelDDR4_2400 --boot-type init --resource-directory tests/gem5/resources --tick-exit 100000000

我们发现没有任何链接器对任何测试的运行时间有显著影响,所有测试都成功完成。 这表明使用链接器不应该对在 gem5 内进行的实验产生任何不利影响。

根据我们的发现,我们可以自信地推荐使用 mold 链接器 来加速构建 gem5 时的链接时间。 如果您有兴趣使用 mold,可以按照这里的说明进行编译。 一旦正确安装,您可以在构建 gem5 时通过传递 --linker=mold 来使用它。

这是一个示例命令:scons build/ALL/gem5.opt -j12 --linker=mold