面向国产 CPU(鲲鹏 / 飞腾 / 龙芯)的 PHP 内核定制编译与优化全流程

  这一篇聚焦到 CPU 本身。上一篇给了通用骨架,这篇把三家国产 CPU 掰开揉碎,每个都给精确到型号的编译参数。核心一句话:

  ▎ 鲲鹏/飞腾是 ARM 系(指令集同源、优化相似),龙芯是 LoongArch 独一家。 前两家几乎一套打法,龙芯要单独伺候。

  ---
  第〇部分:先确认你到底是哪颗 CPU

  一步定位,别猜:

  # ①架构名(决定"ARM系"还是"LoongArch")
  uname -m
  #   aarch64       →鲲鹏/飞腾(或任何ARM)
  #   loongarch64   →龙芯

  # ②具体型号(决定微架构级优化)(/proc/cpuinfo)
  grep -E "model name|Model name|CPU part|cpu model" /proc/cpuinfo | head -5

  # ③看 CPU 部分编号(key) 鲲鹏/飞腾靠 "CPU part" 区分
  awk '/CPU part/{print}' /proc/cpuinfo | sort -u

  # 常见的:
  #   CPU part : 0xd0c  →华为鲲鹏 920 (Kunpeng 920)
  #   CPU part : 0xd09  →飞腾 FT-2000+ / 某代
  #   CPU part : 0x663 / 0x904 x →另一代飞腾 等
  # 更稳: 直接 cat /proc/cpuinfo 看 "model name", 或 lscpu
  lscpu

  注意: 光 uname -m 不够,/proc/cpuinfo 的 CPU part / Model name 才能锁定微架构。

  ---
  第一部分:鲲鹏 920(aarch64)

  1.1 目标机特征

  架构   : aarch64
  核心   : 华为自研(内核 Neoverse 类, 偏服务器)
  特性   : 支持 armv8.2, 有 rcpc/原子指令, 内存模型偏 ARMv8
  定位   : 服务器/数据中心 ——核多, 弱单核, 吃吞吐

  1.2 关键编译参数(精确到 920# ARM 系的精髓: -march + -mtune 对准微架构
  export CFLAGS="-O2 -march=armv8.2-a+rcpc+simd -mtune=neoverse-n1"
  # 为什么:
  #   -march=armv8.2-a   : 920 支持 ARMv8.2 指令集(根本指令)
  #   +rcpc  : 内存一致性扩展(920, 提升原子操作)
  #   +simd  : 打开 NEON SIMD(向量计算/加密加速的前提)
  #   -mtune=neoverse-n1 : 让 GCC 按 920 的流水线微调指令排布
  #   -O2    : 通用优化(别随意上 -O3, 稳定性优先, 信创求稳)

  # 参考: 如果你要针对浮点/加密更狠:
  #   CFLAGS="-O2 -march=armv8.2-a+rcpc+simd+aes+crypto -mtune=neoverse-n1"
  #   +aes, +crypto: 打开硬件 AES/SHA 指令(NEON 里的 crypto 扩展),
  #                  加密/哈希(OpenSSL,GCM)会明显快

  ⚠️先验证你的 GCC 认不认这些 flag:

  gcc -march=armv8.2-a+rcpc+simd -mtune=neoverse-n1 -o /tmp/t /dev/null 2>&1 && \
    echo "gcc 支持这个 march" || echo "gcc 太旧, 降级到 -march=armv8-a -mtune=generic"

  1.3 configure 推荐(鲲鹏 920./configure \
    --prefix=/usr/local/php8 \
    --enable-cli --enable-fpm \
    --enable-opcache=yes --enable-opcache-jit=yes \
    --with-openssl --with-curl --with-zlib \
    --with-sqlite3 --with-pdo-sqlite \
    --with-mysqli --with-pdo-mysql \
    --enable-mbstring \
    --with-pcre-jit \
    CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"

  1.4 鲲鹏专属优化点(比常规多做的)

  ①OpenSSL 硬件加速: 920 有 ARMv8 crypto 指令(aes/sha/ghash)
     →编译 PHP 的 OpenSSL 时确认它编进了 ARM 汇编加速
       (编 OpenSSL 时 ./Configure linux-aarch64)
     →测: openssl speed -evp aes-256-gcm 看单核速度

  ②JIT 有没有用(22阶段铁律: 先分清 CPU 还是 I/O)920 单核弱, 如果你跑纯计算(图像/加密), JIT 收益可观
     →如果你查库/API(I/O 密集), JIT 白开还吃内存 →关

  ③核数多 →FPM max_children 可以开大一点
     →但内存换算优先(920 服务器内存一般足, 可看 32-128G)

  ---
  第二部分:飞腾(Phytium)

  2.1 目标机特征

  架构   : aarch64 (和鲲鹏同指令集)
  主流   : FT-2000+/64, 飞腾 250024 (D2000), 飞腾 8622
  特点   : 桌面/服务器都有; 微架构和鲲鹏不同; 对齐 ARMv8.0 更稳
  定位   : 信创最常见的"办公+服务器"CPU ——你很可能先遇到它

  2.2 关键编译参数

  # 飞腾比鲲鹏保守 ——严格支持 ARMv8.0, 新特性(rcpc/crypto)要确认
  #   稳妥首选(几乎所有飞腾都能编):
  export CFLAGS="-O2 -march=armv8-a -mtune=generic"
  #   →不要一上来就 +rcpc/+crypto, 不同代飞腾支持情况不一,
  #     用 armv8-a 基带最稳, 所有飞腾都认

  # 如果你确认是新款飞腾(如部分 D2000 代)且有 crypto 需要:
  #   先在 /proc/cpuinfo 看有没有 openssl 支持的新特性标记
  grep -o -E "atomics|crc|asimd|crypto" /proc/cpuinfo | sort -u
  # 出现 "atomics crc asimd aes sha1 sha2 pmull" 这类 →可试 +aes+crypto

  # 有 atomics/rcpc(新版才敢):
  #   export CFLAGS="-O2 -march=armv8.2-a+rcpc+simd -mtune=neoverse-n1"

  一句话:鲲鹏可大胆上 v8.2+crypto,飞腾先 v8.0 稳,确认了再升。

  2.3 configure 与验证

  ./configure [和鲲鹏基本一致的清单] CFLAGS="$CFLAGS"

  # 验: 编完确认能跑
  ./php -r 'echo php_uname("m"), " ", GC::getMajor(), PHP_EOL;'
  # 应该输出 aarch64 ...

  ---
  第三部分:龙芯(LoongArch / 龙架构)

  这是最容易翻车、必须单独讲的一段。

  3.1 目标机特征

  架构   : loongarch64 (LoongArch ——龙芯第三大自主指令集)
  版本   : LA464 (3A5000), LA664 (3A6000)
  工具链 : 要求 binutils/gcc 版本够新(LoongArch 的 GCC 支持较晚)
  关键   : 没有 ARM/x86 那些旧汇编积累, 生态依赖最新工具链

  3.2 前置:工具链检查(龙芯的头号大坑)

  # ①确认 GCC 认 loongarch64
  gcc --version
  #   需要 GCC 12+ 对 LoongArch 支持才稳定
  gcc -dumpmachine          # 应含 loongarch64

  # ②确认 binutils
  binutils-version=$(rpm -q binutils 2>/dev/null)
  echo "binutils: $binutils-version"
  #   LoongArch 需要 binutils 2.41+ 才算全支持

  # ③如果太旧 →升级工具链(龙芯官方提供交叉/工具链源)
  #   常见做法: 用龙芯/openEuler 提供的 gcc 12+/binutils 源

  # 最稳: 直接查 os 自带工具链目标
  echo 'int main(){return 0;}' > /tmp/t.c && gcc /tmp/t.c -o /tmp/t && \
    readelf -h /tmp/t | grep -i machine
  # LoongArch 架构 ELF 的 Machine 字段约对应 LoongArch

  3.3 龙芯 PHP 编译(关键:JIT 与 configure)

  # ①龙芯专用宏(PHP 8.2+ 对 loongarch 才有完整 JIT 后端)
  #    如果你用 PHP 8.1 →LoongArch JIT 基本不可用
  #    建议: 龙芯直接用 PHP 8.3+/8.4 (LoongArch JIT 后端完善)

  # ②龙芯 configure(带 JIT)
  ./configure \
    --prefix=/usr/local/php8 \
    --enable-cli --enable-fpm \
    --enable-opcache=yes --enable-opcache-jit=yes \  # ★8.3+ 才建议
    --with-openssl --with-curl --with-sqlite3 --with-pdo-sqlite \
    --enable-mbstring \
    CFLAGS="-O2 -march=loongarch64 -mtune=la464"

  # ③万一 JIT 出问题 →快速回退(先跑稳):
  #   ./configure ... --disable-opcache-jit
  #   →或 php.ini 里 opcache.jit=0

  ⚠️龙芯 JIT 的关键提醒:

  ★龙芯(PHP 8.3+)的 opcache JIT 走 LoongArch 后端, 比 ARM 慢半拍成熟
  ★决策(22阶段铁律):
    - I/O 密集(查库/API) →JIT 收益≈0→关了更省内存更稳
    - 纯 CPU 计算 →测过真快再开
  ★不确定就:--disable-opcache-jit 编个稳的 + PHP 8.3 保底

  3.4 龙芯特有编译期注意事项

  ①不要对龙芯上来就 +aes +crypto 之类, 它的硬件扩展要精确看型号
     (LA464 与 LA664 的 crypto 支持不完全一样)
  ②OpenSSL 对 loongarch 的汇编加速较新 →若有性能缺口另说,
     先用 openssl/md5 测一下
  ③内存一样吃紧 →别贪 -j, 用 nproc 折半

  ---
  第四部分:三方统一要做的"编译前强制检查清单"

  不管你是哪颗 CPU,configure 前把这串跑一遍,避免"编译一小时死在一个缺失库":

  # 检查四个命脉依赖(扩展能否编进)
  echo "--- 依赖库检查 ---"
  for spec in \
    "openssl  --with-openssl" \
    "curl     --with-curl" \
    "xml2     libxml2" \
    "sqlite3  --with-sqlite3" \
    "zlib     zlib" \
    "pcre2    --with-pcre-jit"
  do
    set -- $spec
    printf "%-10s " "$1"
    echo "#include <$1.h>" > /tmp/dep.c 2>/dev/null && gcc -E /tmp/dep.c >/dev/null 2>&1 && \
      echo "header OK" || echo "header MISSING"
  done

  # 实际更可靠的: configure 里是否有对应选项能识别:
  #   →如果 `rpm -q openssl-devel` 都查不到,--with-openssl 必失败
  for p in openssl-devel libcurl-devel libxml2-devel libsqlite3-dev zlib-devel pcre2-devel; do
    rpm -q "$p" >/dev/null 2>&1 || apt list --installed 2>/dev/null | grep -q "$p" \
      && echo "OK  $p" || echo "缺失 $p (先装!)"
  done

  ---
  第五部分:三方通用的性能优化动作(不只编译参数)

  "国产 CPU 单核弱"是共性,所以性能靠并发 + 缓存 + 让硬件加速撑,不只靠编译 flag。

  5.1 编译期立即可拿的(前几节已给)

  ┌──────────────┬────────────────────────────┬──────────────────────┬───────────────────┐
  │      项      │          鲲鹏 920          │     飞腾(D2000)      │ 龙芯(3A5000/6000) │
  ├──────────────┼────────────────────────────┼──────────────────────┼───────────────────┤
  │ CFLAGS       │ armv8.2-a+rcpc+simd+crypto │ armv8-a 保守;新代可+ │ loongarch64+la464 │
  ├──────────────┼────────────────────────────┼──────────────────────┼───────────────────┤
  │ -mtune       │ neoverse-n1                │ generic 稳           │ la464             │
  ├──────────────┼────────────────────────────┼──────────────────────┼───────────────────┤
  │ JIT          │ 测了再开                   │ 同左                 │ 8.3+才考虑        │
  ├──────────────┼────────────────────────────┼──────────────────────┼───────────────────┤
  │ OpenSSL 加速 │ 有 ARM crypto 指令,要编上  │ 确认后也受益         │ 较新,按需         │
  └──────────────┴────────────────────────────┴──────────────────────┴───────────────────┘

  5.2 PHP-FPM 并发调优(国产机通用)

  ; php-fpm pool
  pm = dynamic
  pm.max_children = 200           ; 核数多就大(鲲鹏64核可到几百)
  pm.start_servers = 20
  pm.min_spare_servers = 10
  pm.max_spare_servers = 60
  pm.max_requests = 10000         ; 防泄漏退休
  ; 每台国产机的池子大小 = 内存换算(22/235阶段):
  ;   max_children ≈(可用内存MB) / (单worker峰值MB)

  5.3 用上硬件加速(加密场景必做)

  # 在鲲鹏/飞腾上测硬件 AES 是否真的走了 NEON crypto:
  openssl speed -elapsed -evp aes-256-gcm 2>/dev/null | head
  # 速度高(常见几十万~上百万次/) = 硬件加速生效, 配置 OK
  # 若很慢 →说明 OpenSSL 没编译 ARM 汇编 →重编 OpenSSL linux-aarch64

  ---
  第六部分:三方全面验证(编译通过 ≠能用)

  6.1 一套"架构感知"的最终验证脚本

  # verify-php.sh ——内核定制编译后的完整体检
  #!/bin/bash
  PHP=${1:-./sapi/cli/php}
  echo "=== 1. 架构/版本 ==="
  $PHP -r 'echo PHP_VERSION, " ", PHP_OS, " ", php_uname("m"), PHP_EOL;'

  echo "=== 2. 关键扩展 ==="
  $PHP -m | grep -iE "opcache|pdo|sqlite|curl|openssl|mbstring|intl|pcre" | sort

  echo "=== 3. JIT 状态(若有) ==="
  $PHP -i | grep -i jit || echo "   (未开 JIT)"

  echo "=== 4. SQLite3 真用 ==="
  $PHP -r '
   $db=new SQLite3(":memory:");
   $db->exec("CREATE TABLE t(a INT)"); $db->exec("INSERT INTO t VALUES(42)");
   echo "SQLite3 OK:", $db->querySingle("SELECT a FROM t"), PHP_EOL;'

  echo "=== 5. 加密(用硬件加速自测) ==="
  $PHP -r '
   $t=hrtime(true); for($i=0;$i<20000;$i++) hash("sha256","x".$i);
   printf("sha256 x20000: %.2f ms\n", (hrtime(true)-$t)/1e6);'

  echo "=== 6. 真实负载冒烟(能跑 import 才行) ==="
  $PHP -r 'echo "bench: ";'
  # 你实际把 birddb 的导入脚本小样本跑一遍才算闭环

  6.2 结果该长什么样(读法)

  === 1. 架构/版本 ===
  8.3.14 Linux aarch64           ←CPU 架构对了
  === SQLite3 OK:42 ===          ←你项目的命根活了
  sha256 x20000: 12.34 ms         ←数字不异常(同一代CPU横向比)

  ---
  第七部分:三个 CPU 的特有问题速查(收藏用)

  鲲鹏 920

  ? 遇到 "unsafe: xxxx" 老内核告警 →别怕, 常见, 需更新内核/或阉割
  ? JIT 内存: 鲲鹏核多内存大, JIT 可大开(512M) 但要先测 CPU 密集
  ? 若编不过 armv8.2:-march=armv8-a -mtune=generic 必过

  飞腾

  ? 飞腾有 "安全特性" 可能影响指令集 →用 armv8-a 万能保底
  ? 老飞腾(FT-2000+) GLIBC 可能旧 →选对应 OS 的 PHP 确认能编
  ? 桌面机内存小 →FPM worker 别开太大(内存先算)

  龙芯

  ? LoongArch 工具链太旧是头号杀手 →必查 gcc/binutils
  ? JIT 只 8.3+ 考虑; 不确定就关掉跑稳
  ? 龙芯生态库少 →缺 openssl-devel 之类概率高, 先查依赖
  ? 装 UOS/麒麟龙芯版时, 别以为 arm64 和你 x86 装法一样

  ---
  全篇三句话(记这个就够)

  1. 鲲鹏/飞腾 = ARM 一套打法,但飞腾要保守(鲲鹏敢上 v8.2+crypto,飞腾先 v8.0 稳);龙芯 = LoongArch
  独一套,先验工具链(gcc 12+ / binutils 2.41+),JIT 只在 8.3+ 考虑。
  2. 编译参数不是性能的全部——国产CPU 单核弱,真正的性能来自 OPcache + FPM 并发 + 连接池 + (按需)硬件AES,别指望 -O3
  起飞。
  3. "编完能跑"不等于"适配完成"——必须跑过"架构确认+ SQLite3 真用 + 加密自测 + 小样本导入"四关,才叫国产化适配合格。
Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐