我要准备给领导讲 ccec (华为 NPU 编译器,基于 llvm)实现结构 (1)代码结构...

Tạo vào: 16 tháng 8, 2026

Trả lời bằng GPT-5.6 Thinking bởi Chat01

Câu hỏi

我要准备给领导讲 ccec (华为 NPU 编译器,基于 llvm)实现结构
(1)代码结构
(2)ccec特性能力
(3)多代际支持

应该具体需要哪些方面?只有一天半时间读代码+准备

Suy nghĩ

Searched 14 websites

Worked for 10s

Trả lời

可以把范围压得很明确:一天半不要试图理解所有 Pass 和所有 NPU 指令,而是围绕“一个编译流程 + 三个架构问题”读代码。

从公开资料看,CCEC 即 CCE Compiler;较新的 CANN 文档中,毕昇编译器仍安装在 compiler/ccec_compiler 下,编译工具链还包含 lldcce-ldllvm-objdumpllvm-ar 等。当前公开接口也明确存在 --npu-arch / --npu-soc 这样的架构选择机制。(Hiascend)
所以你的汇报完全可以按 “LLVM 主干框架 + CCE/NPU 定制 + 多架构适配层” 这条主线来组织。

我建议最终只回答 6 个问题

1. CCEC 在整个软件栈里是什么位置?

先用一张图讲清:

text
Ascend C / CCE / intrinsic / builtin Clang Frontend LLVM IR ┌─────────┴─────────┐ │ CCE/NPU IR Passes │ │ LLVM Common Pass │ └─────────┬─────────┘ NPU Backend ISel / RegAlloc / Schedule MC / Asm Object / Device Bin Link / FatObj Runtime

不要一上来讲目录。领导首先应该知道:

CCEC 接收什么,做了什么,输出什么,与 Runtime、算子编程语言、硬件分别是什么关系。

公开文档也能看到 CCE/Ascend C 支持 AI Core device code 以及 host/device 异构编译模式。(Hiascend)


2. “代码结构”不要按目录念,要按编译阶段讲

这是你第一重点。

建议最终总结成下面 5 层,然后把真实代码目录填进去。

你需要找什么汇报时讲什么
Driver / Frontendccec/bisheng driver、参数解析、语言扩展、builtin/intrinsicCCE 如何进入 LLVM
LLVM IR / Middle-endCCE 自定义 Pass、canonicalize、优化哪些复用 LLVM,哪些 NPU 特有
Target BackendTargetMachine、Subtarget、ISel、InstrInfo、RegisterInfoLLVM IR 如何变 NPU 指令
Architecture Adaptationarch/soc/features、CPU/Feature 判断多代 NPU 如何共用一套代码
MC/Link/ObjectMC、object、metadata、lld/cce-ld/fatobj最终 device binary 怎么出来

尤其是 Backend 建议重点看 6 个 LLVM 经典入口

text
TargetMachine Subtarget TargetLowering InstrInfo RegisterInfo FrameLowering

再加:

text
TableGen / *.td Pass pipeline Builtin / Intrinsic definition

你不是要读懂实现,而是回答:

“这个模块负责什么?上游输入是什么?下游输出是什么?”

每个模块能说一句话,就够汇报了。


3. CCEC 特性能力:不要列几十个 feature,分成 4 类

这部分很容易陷进去。

建议按照用户能感知到的能力讲。

A. 编程模型能力

比如你代码里实际存在的:

  • CCE / Ascend C language extension
  • AI Core kernel
  • Vector / Cube
  • intrinsic / builtin
  • address space / memory hierarchy
  • host-device 异构调用

公开编译选项里也能看到 AI Core、Vector/Cube 以及 CCE/Ascend C 等编译概念。(Hiascend)

B. 编译优化能力

重点找 NPU 特有的,而不是 LLVM 自带的:

text
vector / cube lowering memory access DMA / data movement pipeline sync/barrier instruction combine loop address transformation

如果时间紧,只挑 2~3 个最有代表性的 Pass

对每个 Pass 只回答:

text
解决什么硬件问题 识别什么 IR 做什么 transformation 最终得到什么收益

领导通常不会需要你逐行解释算法。

C. CodeGen 能力

这里体现“这是个真正的 NPU compiler backend”:

  • 指令选择
  • 寄存器
  • 指令调度
  • memory/address space
  • ABI / calling convention
  • object generation
  • device link

D. 工程能力

这个经常被忽略,但很好讲:

  • -O0/-O2/-O3
  • debug info
  • sanitizer
  • simulator / CPU simulation
  • static/shared library
  • linker / objdump
  • diagnostics

这些能力在当前公开编译器文档中都有对应选项或工具。(Hiascend)

这样你的“特性能力”不会变成 feature list,而是:

语言 → 优化 → 后端 → 工程化


4. “多代际支持”其实是这次最值得深挖的一部分

如果领导是技术领导,我会把这里当成你的亮点

不要只说:

支持 Ascend xxx / xxx / xxx。

这意义不大。

真正应该回答的是:

同一个 CCEC 如何同时支持不同 NPU ISA/微架构?

建议沿着下面这条链找代码:

text
--npu-arch / --npu-soc Arch / CPU / Feature Parsing Subtarget / | \ FeatureA FeatureB FeatureC │ │ ├───────┤ IR Lowering / Intrinsic Instruction Selection Scheduling / Hazard Binary

公开接口已经明确把**产品型号 (--npu-soc)NPU architecture (--npu-arch)**区分开,这恰好可以作为你读多代支持代码的入口。(Hiascend)

你重点找下面 7 类差异点

  1. ISA 差异
    哪些指令只有新架构有?

  2. Feature capability
    有没有类似:

    cpp
    hasXXX() isArchXXX() FeatureXXX
  3. Intrinsic / builtin 差异
    同一个 API 在不同代际是不是 lower 成不同指令?

  4. 数据类型差异
    FP16 / BF16 / INT8 / 新 datatype 谁支持?

  5. memory hierarchy 差异
    buffer/address space/cache/DMA 是否变化?

  6. schedule / pipeline 差异
    同样 ISA,微架构 latency/resource 是否不同?

  7. ABI / binary 差异
    object metadata、link、kernel metadata 有没有代际信息?

其中前三个最重要


5. 最值得准备的一张图:新 NPU 是怎么接进 CCEC 的

你的汇报如果能回答这个问题,会比单纯介绍目录强很多。

假设来了 NPU Gen N+1,你可以从代码总结它需要改哪些层:

text
New NPU ┌───────────┴───────────┐ ▼ ▼ Arch definition Feature set │ │ └───────────┬───────────┘ Subtarget ┌───────────────┼──────────────┐ ▼ ▼ ▼ Intrinsic Lowering New Instr support rule / *.td │ │ │ └───────────────┼──────────────┘ Scheduling Model MC / Binary

然后给领导一个结论,例如:

CCEC 的多代支持不是复制一套 backend,而是尽可能复用公共编译流程,将代际差异收敛到 Architecture/Feature → Subtarget → Lowering/Instruction/Scheduling 几个层次。

当然,这句话最后必须根据你看到的实际代码确认。如果实际代码大量 if (arch == XXX),那反而是个非常值得讲的架构观察。


6. 代码一定选“一条真实 case”串到底

这是你一天半里性价比最高的事情

找一个非常简单的 intrinsic/kernel,例如:

cpp
vector_add

或者一个简单的:

cpp
DataCopy vector intrinsic cube intrinsic

然后追踪:

text
源码 Builtin / Intrinsic LLVM IR CCE-specific Pass ISel / Lowering MachineInstr 最终 NPU Instruction

不要追复杂算子。

有了这一条以后,你前面所有内容都能落地:

  • 代码结构 → 这条 flow 经过哪些目录
  • 特性能力 → intrinsic 怎样实现
  • 多代支持 → 在哪一步根据 arch 分叉

一条 case 顶读十几个零散 Pass。


一天半我建议这样安排

第一天上午:只建立地图,约 3 小时

不要精读。

目标产物只有一张:

CCEC Code Map

先找到:

text
main/driver clang extension LLVM pass registration TargetMachine Subtarget InstrInfo *.td MC link tests

然后把实际目录填到:

text
CCEC ├── Frontend ├── IR/MiddleEnd ├── Backend │ ├── Arch │ ├── Lowering │ ├── Instruction │ ├── Register │ └── Schedule ├── MC/Link └── Tests

此时禁止深入某个 Pass 超过 15 分钟


第一天下午:追一条编译链,约 3 小时

选一个简单 kernel。

最终必须得到:

text
Source XXX.cpp XXX intrinsic XXX pass XXX lowering XXX instruction

这个才是你汇报的主心骨。


第一天下午后半:专门读多代际,约 2 小时

全局搜:

text
arch npu_arch soc subtarget feature hasFeature isArch CPU generation dav

尤其从:

text
--npu-arch

向下追。

然后做一个表:

差异Gen AGen B代码控制位置
intrinsicSubtarget/Lowering
instruction X×InstrInfo/TableGen
datatype X×Feature
schedulingmodel Amodel BScheduleModel

哪怕最后只有 3 行真实例子,都非常有价值。


第二天上午:准备汇报,约 3~4 小时

我建议最终 6~7 页 PPT 足够

P1:CCEC 定位

text
CCE/Ascend C → CCEC → NPU Binary

一句话定位。

P2:整体代码架构

text
Frontend → LLVM IR → Optimization → Backend → MC/Link

下面标对应代码目录。

P3:一次编译到底发生了什么

放你真实追出来的 case。

P4:CCEC 的核心能力

text
Programming Model Optimization CodeGen Toolchain

不要列 30 项 feature。

P5:多代际架构

核心图:

text
Arch Feature/Subtarget Lowering / Instr / Schedule

P6:两个代际差异的真实代码案例

这是最重要的“我真的读了代码”的证据。

P7:总结

最好只讲三个判断:

  1. 架构上:CCEC 基于 LLVM XXX 层进行了主要 NPU 定制。
  2. 能力上:核心价值集中在 XXX lowering / instruction / memory / scheduling。
  3. 演进上:通过 XXX 机制隔离公共逻辑与 NPU 代际差异。

时间紧的话,哪些东西直接不看

我会直接放弃:

  • LLVM 通用优化 Pass 的实现
  • parser 细节
  • diagnostics 细节
  • 所有 intrinsic
  • 所有指令定义
  • register allocator 算法本身
  • LLVM 基础设施
  • 单测逐个看
  • build system 细节

除非它们跟多代际直接相关。

一天半最危险的情况就是上午打开一个 3000 行 XXXLowering.cpp,下午还在里面。


最后给你一个判断标准:你读完代码以后,只需要能够在白板上不看资料画出这张图,就已经基本达到目标:

text
CCEC ┌───────────────┼────────────────┐ │ │ │ Frontend Middle-end Backend │ │ │ CCE/Ascend C NPU Pass ┌─────┴──────┐ Builtin LLVM Pass │ │ Common Subtarget ┌──────┼──────┐ │ │ │ Gen1 Gen2 Gen3 │ │ │ └──────┼──────┘ Lowering / ISel / Schedule Binary

如果只能额外深挖一个方向,我会选“多代际到底在哪几个代码层次分叉”。 这比多认识 20 个优化 Pass 更适合向领导汇报,因为它能直接说明 CCEC 的架构设计、可维护性和新芯片 bring-up 成本

Chia sẻ Q&A này