随着国产芯片与 ARM 生态的快速发展,如何在 ARM 平台上构建高性能存储基础设施成为技术焦点。Linaro 是一个专注于 Arm 生态和开源软件的国际化技术组织,联合产业链上下游厂商解决共性问题,并协助企业客户在开源基础上完成产品化落地。Linaro 团队在 MLPerf Storage 测试中,对 JuiceFS 社区版(元数据采用 Redis)进行了系统压测,覆盖多种典型机器学习训练负载。
测试结果显示,系统性能在很大程度上受内存带宽和元数据访问效率影响,JuiceFS 的吞吐能力直接决定 GPU 利用率及训练效率。通过 UNet3D、ResNet-50 和 CosmoFlow 等负载的测试,分析发现:单机场景下,GPU 利用率主要受内存拷贝延迟限制;在双机或多机场景下,元数据访问和节点间同步成为主要瓶颈。文章同时提供了针对这些瓶颈的调优思路与实践结果。
总体来看,大规模 AI 训练性能调优是一个系统工程,需要从存储系统、内存带宽、CPU 调度、缓存策略等多方面协同优化,才能在 ARM 平台上实现高效的深度学习训练数据供给。
01 Arm64 与 x86_64 架构差异与并发特性概述
相比 x86,Arm 的应用范围不断扩大,已从移动端延伸至 IoT、可穿戴设备、PC、汽车和服务器,其高能效比(performance per watt)是广泛采用的关键原因。
从架构设计上看,Arm 属于 RISC(Reduced Instruction Set Computer,精简指令集计算机),x86 属于 CISC(Complex Instruction Set Computer,复杂指令集计算机)。这种设计差异也影响了处理器的执行方式。Arm64 的指令长度固定为 4 字节,而 x86 指令长度可变,大约在 1–15 字节 之间,因此 x86 往往需要更复杂的译码器。相比之下,Arm 的指令更简洁,也更依赖编译器和代码生成阶段对指令的有效组织,所以需要更长的编译时间。
从工程师可感知的角度来看,还有一些架构差异会直接影响程序行为。很多在 x86 上看起来符合直觉的代码,在 Arm 上未必如此,后面要讲到的几个容易踩坑的点,基本都与这些底层差异有关。
其中一个典型问题是原子操作对地址对齐有要求。无论是 LL/SC(Load-Link/Store-Conditional),还是 LSE(Large System Extensions),在执行原子加减等读改写操作时,通常都要求访问地址满足对齐条件。较新的 LSE2 对这一限制有所放宽,开始支持 16-byte window 内的非对齐访问。数据对齐对于 x86 来说不是必须的,但保持良好对齐有助于提升性能。参考文档: Arm Architecture Reference Manual for A-profile architecture
另一个需要重点关注的特点是,Arm 采用的是弱内存序模型(weakly ordered / relaxed memory model),差别体现在对内存访问顺序的约束强弱不同。在多线程场景下,同样的读写操作,在 x86 上通常更容易表现为接近程序书写顺序,而在 Arm 上则允许更多重排序,因此其他线程观察到的读写顺序可能与源码顺序不一致。在 Arm 上出现的异常需要特别考虑内存序的影响。更多细节可参考 Arm 白皮书:Synchronization Overview and Case Study on Arm Architecture。
02 JuiceFS 与 MLPerf 概述
JuiceFS 是一款开源高性能分布式文件系统,基于对象存储构建,在充分利用对象存储低成本优势的同时,提供接近传统文件系统的使用体验。它支持 POSIX、HDFS SDK、Python SDK 以及 S3 兼容接口,并能适配不同类型的应用和数据处理框架;同时支持云原生扩展、数据安全与压缩,可广泛应用于 AI 训练、推理、大数据处理等场景。
为了深入分析客户端带宽受限的原因,我们对进程进行了 CPU 绑定,将其固定在 CPU1(NUMA 2、3 节点)运行。通过工具观察,48 个 CPU 核心几乎全部占满,进一步分析 top-down、memory 和 miss 指标发现,系统表现出明显 Memory Bound,主要耗时集中在内存拷贝上。这说明,在 CPU 绑定场景下,JuiceFS 性能瓶颈主要来自 CPU 处理能力和跨 NUMA 节点内存拷贝带来的额外延迟。
优化分析 2: 不进行 CPU 绑定
为了理解系统在更通用条件下的带宽限制,我们进一步观察了不绑定 CPU 的情况。通过观察可以看到,CPU 并未被完全用满,但 devkit tuner numafast 指标显示,系统中的 remote 内存访问比例高达约 80%。这意味着,大量内存访问已经跨越本地 NUMA 节点,甚至可能跨越 CPU socket,从而引入了显著的带宽损失和访问时延。
从硬件带宽特性看,跨片内存访问本身就存在明显限制。例如,在 Arm 平台上,跨 socket 的理论物理带宽约为 60 GB/s;进一步通过实测,跨片 copy 带宽在 Arm1 上约为 48 GB/s,而在两组 x86 平台上分别约为 37 GB/s 和 28 GB/s。
这说明,在不绑定 CPU 的情况下,虽然计算核表面上没有被完全耗尽,但大量跨节点、跨 socket 的远端内存访问已经成为新的主要开销来源。因此,可以推测,此时 JuiceFS 带宽无法继续提升,很可能并不是单纯受限于 CPU 算力,而是受限于跨片内存访问的带宽与时延。换言之,系统瓶颈已经从“本地 CPU 忙不过来”转移为“远端内存访问代价过高”。
综合来看,在两种场景下,JuiceFS 带宽无法提升的原因并不相同:
绑定 CPU 时,主要受限于 CPU 资源消耗以及大量内存拷贝带来的访问开销;
不绑定 CPU 时,主要受限于高比例 非本地内存访问,尤其可能是跨 socket 访问带来的带宽和时延损失。