ILP32
简体中文

性能数据

同样的编译方式下对比 ILP32 和 LP64:节省的是内存,代价是几个百分点的速度。

OpenWrt One 实机

OpenWrt One(MT7981B,双核 Cortex-A53,最高 1.3 GHz,1 GB)。两个镜像来自同一份源代码, 软件包(LuCI、python3-light、dnsmasq)与内核配置都相同,也都用 GCC 14.3 编译,只有用户空间的 ABI 不同 (两个内核由同一份源代码、分别构建的工具链编译)。负载:200 条防火墙规则、50 条静态 DHCP、 15 万个域名的 dnsmasq 拦截列表、LuCI 请求,以及一个持有 10 万条 dict 的 Python 进程。每种各启动 3 次,取中位数。

内存LP64ILP32差异
用户空间内存(所有进程 PSS 合计)38.3 MB28.9 MB-24.6%
匿名内存30.3 MB20.9 MB-31%
可用内存(MemAvailable)863.6 MB872.2 MB+8.6 MB
python3(10 万条 dict)17.9 MB12.4 MB-31%
dnsmasq(15 万条拦截列表)12.0 MB8.8 MB-26%
hostapd / wpa_supplicant-11% / -9%
内核(Slab)28.0 MB27.9 MB-0.6%
耗时(秒,越低越好;用 GCC 编译)LP64ILP32差异
重新加载 200 条防火墙规则2.582.84+10%
dnsmasq 加载 15 万条2.963.03+2%
LuCI 登录页 20 次请求1.731.81+5%
python3 构建 10 万条 dict0.380.42+11%

两个镜像的内核都是 LP64,所以内核内存不变;节省的是程序本身的内存,数据越多省得越多。 空闲的路由器只省几百 KB。多出的耗时主要来自在 64 位代码中处理 32 位指针,在为 64 位 long 编写了快速路径的代码中会更慢。把最常用的软件包(ucode、lucihttp、json-c)改用 clang 编译后, 防火墙重新加载为 2.63 秒(+2%),LuCI 请求为 1.76 秒(+2%),内存不变(同一台 OpenWrt One,各启动 3 次取中位数)。只有 ILP32 镜像的这些软件包改用 clang;LP64 镜像只用 GCC 编译, LP64 用 clang 编译的版本尚未测量,所以部分提升可能来自 clang 本身。 同样的测试在 QEMU(armsr,256 MB)上的结果:用户空间内存 -26.0%,可用内存 +9.6 MB。

Cortex-A35 与 Cortex-A53 板子上的 CPython

LP64 和 ILP32 使用相同的 CPython 编译方式:ILP32 内存占用减少约 30%, 在 Cortex-A53 上慢 2.6%,在 Cortex-A35 上慢 5.7%。 编译方式、参数和各项数据:llvm-ilp32 docs/benchmarks.md。

我们如何对比