Skip to content

Tools OV OPs Impl #533

@junxnone

Description

@junxnone

OpenVINO Ops Impl

  • CPU/GPU/NPU 都根据自己的计算架构实现了适合自己的kernel

CPU vs GPU

概念 GPU Kernels(OpenVINO) CPU Kernels(OpenVINO)
本质定义 运行在 GPU 上的独立并行执行单元,基于 OpenCL/C++ SYCL 编写,编译为 GPU 可执行代码 无严格意义上的“Kernel”,是基于 oneDNN 封装的算子逻辑,通过 CPU 向量指令集(AVX2/AVX512)并行执行
存在形式 独立的 .cl(OpenCL)模板文件(如 reorder_bfyx.clcrop_blocked.cl 嵌入在 C++ 代码中的算子逻辑(如 src/plugins/intel_cpu/src/operators/crop.cpp),依赖 oneDNN 原语
编译方式 运行时/离线编译为 GPU 二进制代码(SPIR-V/OpenCL Binary) 编译为 CPU 机器码(x86_64),运行时直接调用(无额外 Kernel 编译步骤)

核心维度对比

对比维度 GPU Kernels CPU Kernels(算子逻辑)
硬件架构适配 面向 众核并行架构:数千个轻量级流处理器(SP),适合大规模数据并行;
核心是“单指令多线程(SIMT)”,一个 Kernel 被多个 GPU 线程同时执行。
面向 多核串行+向量并行架构:少数(几核~几十核)高性能核心,适合复杂逻辑+小批量数据并行;
核心是“单指令多数据(SIMD)”,通过向量指令(AVX512)在单个核心内并行处理 8/16 个数据。
执行方式 1. 以“线程网格(Grid)-线程块(Block)-线程(Thread)”层级调度;
2. 每个 Kernel 是独立的执行单元,需单独启动(有 Kernel 调度开销);
3. 典型如 crop Kernel 被数百个 GPU 线程并行执行,每个线程处理一个像素/通道分片。
1. 以“进程/线程-核心-向量寄存器”层级执行;
2. 无独立 Kernel 启动,算子逻辑“内联”在 CPU 线程中执行;
3. 典型如 crop 逻辑通过 AVX512 指令,单个 CPU 核心一次处理 16 个通道的像素裁剪。
内存模型 多级异构内存:
- 全局内存(Global Memory,慢,GB 级);
- 局部内存(Local Memory,中,KB 级);
- 私有内存(Private Memory,快,寄存器);
Kernel 优化核心是减少全局内存访问(如用 Local Memory 缓存数据)。
统一内存模型:
- 系统内存(DDR4/DDR5)+ CPU 缓存(L1/L2/L3);
优化核心是提升缓存命中率(如数据预取、阻塞格式适配缓存行)。
并行粒度 细粒度并行:
单个 Kernel 可调度数千个线程,每个线程处理单个数据元素(如一个像素、一个通道分片);
适合大规模数据(如图像、特征图)。
粗粒度并行:
以“向量宽度”为粒度(如 AVX512 一次处理 16 个 float32 数据),单个 CPU 核心处理一批数据
适合中等规模数据+复杂逻辑(如小批次推理、算子融合)。
优化方向 1. 内存格式适配:如 b_fs_yx_fsv16 阻塞格式,匹配 GPU 16线程子组;
2. 减少全局内存访问:用 Local Memory 缓存中间结果;
3. 线程同步:优化 Block 内线程协作;
4. 数据类型:优先 FP16/BF16(GPU 原生支持)。
1. 指令集适配:自动选择 AVX2/AVX512/VNNI 指令;
2. 缓存优化:适配 64 字节缓存行(如 nChw16c 格式);
3. 算子融合:将 crop+reorder 合并为一个逻辑,减少内存拷贝;
4. 多核调度:均衡分配任务到多个 CPU 核心。
典型示例(crop) 1. 有独立 crop_blocked.cl Kernel;
2. 按 GPU 线程块拆分裁剪区域,每个线程处理一个空间位置的通道分片;
3. 直接操作 GPU 阻塞格式(无需转回线性)。
1. 无独立 Kernel,通过 dnnl::slice 原语实现;
2. 以向量指令为单位裁剪(如一次处理 16 个通道);
3. 适配 CPU 阻塞格式 nChw16c,通过寄存器缓存数据。
调度开销 高:每个 Kernel 启动需经历“参数传递→网格配置→线程调度”,频繁启动小 Kernel 会有明显开销;
OpenVINO 优化方式:算子融合(如 reorder+crop 合并为一个 Kernel)。
低:无 Kernel 启动开销,算子逻辑直接在 CPU 线程中执行;
OpenVINO 优化方式:多核并行调度,充分利用所有 CPU 核心。
格式支持 专用阻塞格式:b_fs_yx_fsv16/b_fs_zyx_fsv32(适配 GPU 线程子组) 专用阻塞格式:nChw8c/nChw16c(适配 CPU 向量指令宽度)

关键场景化差异

1. 推理场景适配

  • GPU Kernels:适合大批次、高分辨率推理(如 16 批次 224×224 图像),利用数千线程并行处理,吞吐量高;
  • CPU Kernels(算子):适合小批次、低延迟推理(如 1 批次推理),通过核心内向量并行+低调度开销,保证响应速度。

2. 算子融合能力

  • GPU:融合受 Kernel 编译限制,仅能融合逻辑简单的算子(如 reorder+crop);
  • CPU:融合能力更强,可将“卷积+BN+激活+裁剪”合并为一个算子逻辑,完全消除中间内存拷贝。

3. 调试方式

  • GPU Kernels:可通过 OV_GPU_DUMP_SOURCES_PATH 导出编译后的 OpenCL 代码,用 Intel GPA 工具分析 Kernel 执行时间;
  • CPU 算子:通过 oneDNN 性能分析工具(dnnl_verbose=1)查看指令集使用、缓存命中率,或用 VTune 分析 CPU 核心利用率。

总结

核心结论 关键要点
本质差异 GPU Kernels 是独立并行执行单元,CPU 无真正 Kernel,仅为指令集优化的算子逻辑;
执行逻辑 GPU 是“众核细粒度并行”(线程级),CPU 是“多核粗粒度并行”(向量指令级);
优化核心 GPU 优化内存访问(减少全局内存调用),CPU 优化缓存命中率+指令集利用率;
场景适配 GPU 适合大批次高吞吐量,CPU 适合小批次低延迟;

简单来说,GPU Kernels 是为“大规模数据并行”设计的独立执行单元,而 CPU 侧无真正 Kernel,是为“核心内向量并行+多核调度”设计的算子逻辑——两者的差异本质是 CPU/GPU 硬件架构的差异在 OpenVINO 算子层的体现,OpenVINO 会自动适配两者的优化逻辑,让用户通过统一 API 调用即可获得最优性能。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions