编译
ncnn的编译安装官方仓库提供的教程还是蛮详细的,这里笔者参考Raspberry Pi编译的教程提供在radxa o6板子上的完整编译命令
git clone https://github.com/Tencent/ncnn.git
cd ncnn
git submodule update --init
sudo apt install build-essential git cmake libprotobuf-dev protobuf-compiler libomp-dev libopencv-dev
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DNCNN_VULKAN=ON -DNCNN_BUILD_EXAMPLES=ON ..
make -j$(nproc)这里注意一下:NCNN_BUILD_BENCHMARK默认是打开的,如果想要看到模型每个layer的耗时编译的时候可以设置:-DNCNN_BENCHMARK=ON
运行
运行benchmark主要关注网络结构本身的计算耗时,而不是具体的推理结果,所以只需要网络结构定义文件(即 ncnn 的 .param 文件)拷贝到编译好的benchmark文件夹内
cd build/benchmark
cp ../../benchmark/* ./运行参数解读
| 参数 (Parameter) | 选项 (Options) | 默认值 (Default) | 说明 (Description) | 
|---|---|---|---|
| loop count | 1 到 N 的整数 | 4 | 指定推理测试循环执行的次数,用于计算平均性能。 | 
| num threads | 1 到 N 的整数 | max_cpu_count | 指定用于推理的 CPU 线程数量。默认使用所有可用的 CPU 核心。 | 
| powersave | 0=所有核心, 1=仅小核, 2=仅大核 | 0 | 控制 CPU 核心的使用策略,用于功耗或性能测试(适用于大小核架构)。 | 
| gpu device | -1=仅CPU, 0=GPU0, 1=GPU1 ... | -1 | 指定使用的 GPU 设备进行推理。-1 表示仅使用 CPU。 | 
| cooling down | 0=禁用, 1=启用 | 1 | 是否在每次循环测试之间启用冷却等待,以避免过热影响性能测试结果。 | 
| param | ncnn 模型 .param文件路径 | - (必须提供) | 指定要进行性能测试的 ncnn 网络结构定义文件( .param文件)。 | 
| shape | 模型输入形状,格式为 width,height,channels等 | - (必须提供) | 指定模型输入的形状(例如 224,224,3)。 | 
Benchmark
这里分别在CPU和GPU上运行Benchmark程序,并使用Gemini2.5 Pro大模型对结果数据进行解读
CPU测试
./benchncnn 4 8 0 -1 1
结论:
- 测试环境: 本次测试在 CPU 上进行,使用了 8 个线程,并启用了核心间冷却。
- 性能差异显著: 不同模型的推理速度差异很大。 - 最快梯队: 轻量级模型如 blazeface(平均 1.95ms),shufflenet_v2(平均 2.96ms),squeezenet_int8(平均 3.15ms) 表现最佳。
- 最慢梯队: 复杂模型如 vision_transformer(平均 232.46ms) 和vgg16(平均约 42ms) 耗时最长。
 
- 最快梯队: 轻量级模型如 
- INT8 量化效果: 对于支持 INT8 的模型,其量化版本(如 squeezenet_int8,mobilenet_int8,resnet50_int8)通常比对应的浮点版本(FP32)运行更快,验证了量化在提升 CPU 推理速度上的有效性。
- 模型复杂度影响: 总体而言,模型越复杂(如 VGG, ResNet50, ViT),推理时间越长;模型越轻量(如 SqueezeNet, MobileNet, ShuffleNet),推理时间越短。 - GPU测试- ./benchncnn 4 8 0 0 1
 参数解读
- 测试环境: 本次测试主要在 GPU (Mali-G720-Immortalis) 上进行,同时指定了 8 个 CPU 线程,并启用了核心间冷却。
- INT8 优势: 对于大多数支持 INT8 的模型,其量化版本在 GPU 上的表现依然优于或接近 FP32 版本(例如 squeezenet_int8,mobilenet_int8,resnet18_int8,resnet50_int8,mobilenet_ssd_int8)。但也存在例外,如vgg16_int8反而比vgg16慢。
- 模型性能差异: 不同模型在 GPU 上的性能差异仍然很大。 - 较快模型: squeezenet_int8(平均 3.16ms),mobilenet_int8(平均 3.51ms),mobilenet(平均 3.76ms) 等表现较好。
- 较慢模型: vision_transformer(平均 1081.32ms) 耗时极长,efficientnetv2_b0(平均 124.66ms) 和一些目标检测模型(如mobilenetv2_yolov3,yolov4-tiny)也相对较慢。
 
- 较快模型: 
- 波动性: 某些模型(如 - mobilenet_v3,- mnasnet,- efficientnet_b0)的最大耗时远高于平均耗时,可能表明 GPU 在运行这些模型时存在一定的性能波动或初始化开销。- 对比- 模型 (Model) - CPU 平均耗时 (ms) - GPU 平均耗时 (ms) - GPU 相对 CPU 加速比 - squeezenet - 5.62 - 16.57 - ~0.34x (变慢) - squeezenet_int8 - 3.15 - 3.16 - ~1.00x (持平) - mobilenet - 5.25 - 3.76 - ~1.40x - mobilenet_int8 - 3.46 - 3.51 - ~0.99x (持平) - mobilenet_v2 - 4.11 - 4.85 - ~0.85x (变慢) - shufflenet_v2 - 2.96 - 15.22 - ~0.19x (变慢) - blazeface - 1.95 - 6.17 - ~0.32x (变慢) - resnet18 - 6.79 - 7.39 - ~0.92x (略慢) - resnet18_int8 - 5.08 - 4.34 - ~1.17x - vgg16 - 42.23 - 32.07 - ~1.32x - vgg16_int8 - 42.11 - 44.89 - ~0.94x (略慢) - resnet50 - 14.11 - 16.55 - ~0.85x (变慢) - resnet50_int8 - 8.67 - 8.55 - ~1.01x (持平) - mobilenet_ssd - 7.70 - 18.86 - ~0.41x (变慢) - mobilenet_ssd_int8 - 7.12 - 5.64 - ~1.26x - yolov4-tiny - 16.10 - 60.69 - ~0.27x (变慢) - vision_transformer - 232.46 - 1081.32 - ~0.21x (变慢) 
结论总结
- GPU 并非普遍优于 CPU: - 与预期不同,在此设备和 ncnn 框架下,Mali GPU 并未对所有模型提供加速。
- 相当一部分模型(包括 FP32 和部分 INT8)在 GPU 上的运行速度显著慢于在 8 核 CPU 上的速度。例如 vision_transformer,yolov4-tiny,shufflenet_v2,squeezenet(FP32) 等。
 
- INT8 量化是关键,相对提升 GPU 表现: - INT8 量化模型在 CPU 和 GPU 上通常都远快于其 FP32 版本。
- 对于 GPU 而言,INT8 模型的表现相对优于 FP32 版本。部分 INT8 模型(如 resnet18_int8,mobilenet_ssd_int8)在 GPU 上实现了对 CPU 的加速,而它们的 FP32 版本在 GPU 上反而更慢。
- 一些 INT8 模型在 CPU 和 GPU 上的性能非常接近(如 squeezenet_int8,resnet50_int8),显示 GPU 并未带来额外优势。
 
- 少数模型确实受益于 GPU: - 存在少数模型,即使是 FP32 版本,在 GPU 上也获得了实际的性能提升,例如 mobilenet和vgg16。
 
- 存在少数模型,即使是 FP32 版本,在 GPU 上也获得了实际的性能提升,例如 
- 最终建议: - 不能默认 GPU 更快。在此平台上使用 ncnn 时,CPU(特别是结合 INT8 量化)在许多场景下是性能更优的选择。
- 必须通过实际基准测试(如 benchncnn)来评估特定模型,以确定选用 CPU 还是 GPU 能获得最佳性能。
 

 
                