一、和AMDXDNA的区别Intel IVPU 是以 SHAVE 向量核阵列 CMX 共享暂存器为核心采用单层直通提交、参数化动态 Shape 适配、固件自治调度的客户端低功耗 NPU。Intel的Ivpu和AMDXDNA架构还是有很大区别的AMDXDNA是2d空间阵列计算核心的代码放在每个Tile的计算核心机器码存储在16k的progamme memory里执行的时候会从0地址执行一直到done为止数据在每个Tile间流动。关于AMDXDNA的架构可以参考这篇文章写得挺好的探秘 AMD NPU 的底层编程接口对比和高通 NPU 的差异 - 知乎和AMDXDNA的整个执行阶段计算核心机器码是放在每个Tile的16k的programme memory不同Intel的计算核心是一个叫做shave的dsp他的指令是放在host端的ddr ram里的。当运行的时候再搬到shave的cache类似于这样[编译期] VPUX 生成 .blob → 用户态 mmap 写入 GEM BO (instr_bo)↓[驱动期] drm_gem_object 分配在系统内存 (Host DDR/CMA)→ IOMMU 映射 → 生成 NPU 可见的 IOVA 地址↓[运行期] NPU Command Streamer 解析 batch_bo→ 遇到 CMD_EXEC_KERNEL → 硬件指令 DMA 引擎启动→ 通过 IOMMU 直接从 Host DDR 按序拉取指令块→ 填入 SHAVE 片上 I-Cache (32~64KB)→ SHAVE 核从 I-Cache 取指执行二、任务队列里放啥之前说过amdxdna的任务队列放的是command buffer这个command最终有可能会调用到64M的Instruction buffer去执行npu相关的dma、以及启动kernel之类的操作。那么在Ivpu体系中和Instruction buffer对等的一个概念是batch buffer只不过batch buffer里的内容因为intel是闭源的我们无从知晓但是大概可以猜到无非还是dma、执行kernel之类。看一下ivpu的job结构体batch buffer是嵌入在这个结构中的c// 文件vpu_jsm_api.h:L243-267 struct vpu_job_queue_entry { // ⭐ 核心指向 Batch Buffer命令包 u64 batch_buf_addr; // ← Batch Buffer 的 VPU 地址 u32 job_id; // Job ID u32 flags; // 标志位 u64 doorbell_timestamp; // Doorbell 时间戳 u64 host_tracking_id; // Host 追踪 ID // 抢占缓冲区可选 u64 primary_preempt_buf_addr; u32 primary_preempt_buf_size; u32 secondary_preempt_buf_size; u64 secondary_preempt_buf_addr; };与固化的Instruction buffer不同batch buffer是每次任务提交都会产生新的内容的特性AMD XDNAIntel VPU (ivpu)代码存储Instruction Buffer(64MB, 持久化)Batch Buffer(嵌入在 Job 中一次性)命令提交Command Buffer (含 Inst Buffer 指针)Job Queue Entry (含 Batch Buffer 地址)固件角色ERT 读取 Inst Buffer 执行Firmware 解析 Job Queue Batch Buffer生命周期Inst Buffer 与 Context 同生共死Batch Buffer 随 Job 提交即释放映射方式双重映射用户态 ERT仅设备映射通过 MMU三、计算核心机器码放在哪里一次大模型的编译最终会生成一个大的elf文件其中会把需要用到的kernel函数都放进去。参考一下SHAVEIntel NPU 里的可编程处理器 - 知乎在npu_compiler仓库里sw_runtime_kernels/kernels/prebuild/act_shave_bin/目录下存放了所有预编译好的 SHAVE kernel ELF。截至目前这个目录包含719 个 ELF 文件覆盖195 个不同的 kernel family横跨 4 种架构变体3720xx、3720xx_lsu0_wo、4000xx、5000xx。这些 ELF 被提交到仓库原因很直接编译器需要它们才能工作。编译器在处理模型时遇到需要 SHAVE 执行的操作就会从这个预编译库里按 kernel 名和目标架构查找对应的 ELF提取代码和数据段嵌入最终的 NPU 可执行文件。没有这些 ELF编译器就无法为 SHAVE 生成任何任务。假设这个大的elf文件是如下结构model.blob (最终产物) ├─ Header (Magic, Version, Signature, Kernel CountN) ├─ .text ← 所有 Kernel 的 VLIW 指令流线性拼接 │ ├─ [0x0000 ~ 0x1A40] Kernel_0 (ConvReLU) │ ├─ [0x1A40 ~ 0x3C20] Kernel_1 (MatMulKV) │ └─ [0x3C20 ~ 0x5E00] Kernel_2 (LayerNormSoftmax) ├─ .kernel_desc ← 索引表{id, entry_offset, size, params_layout} ├─ .cmx_layout ← 全局内存分区规划多 Kernel 复用/隔离策略 └─ .tiling_table ← 动态 Shape 适配公式在推理进行的时候runtime会根据需要组装成不同的batch buffer这些batch buffer命令最终会调用到具体的kernel。场景行为batch_bo变化顺序执行如 Conv → MatMul → Softmax插件按依赖链依次提交entry_offset从0x0000→0x1A40→0x3C20切换条件分支/动态路由插件根据输入 Shape/分支条件选择 Kernelentry_offset动态跳转instr_bo_iova不变多请求并发同一.blob被多个infer_request引用各请求独立构建batch_bo共享同一instr_bo基址