#6765·ncnn

Inference results are not deterministic due to uninitialized padding memory in Mat::create()

Author: suncan0207Created Jun 1, 2026Updated Sep 3, 2026

error log | 日志或报错信息 | ログ

无崩溃日志。

现象如下:

使用相同模型、相同输入图片,多次重复推理时结果存在轻微差异。 在部分场景下会偶发检测轮廓缺失或分割结果异常。 问题出现概率与运行次数、线程调度及内存复用情况相关。 Windows x64(MSVC)环境下较容易复现。 context | 编译/运行环境 | バックグラウンド ncnn: (20260526) OS: Windows 10/11 x64 Compiler: Visual Studio 2022 (MSVC) Architecture: x86_64 Vulkan: ON(默认配置) OpenMP: ON(默认配置)

经过排查发现,问题可能与 Mat 内存分配后未初始化有关。

当前实现中:

Mat::create() 调用 fastMalloc() 分配内存后未进行初始化。 当 cstep 对齐产生 padding 区域时,该区域可能包含历史内存数据。 PoolAllocator 复用内存块时也不会清零。 x86 SIMD Packing(elempack=4/8/16)场景下,当通道数不能整除 pack 大小时,部分 lane 保留未初始化数据。 后续卷积计算会读取这些未初始化值,从而导致同一输入在不同运行间出现结果差异。 how to reproduce | 复现步骤 | 再現方法 使用 x86 Windows 环境编译 ncnn(默认配置即可)。 加载任意检测或分割模型。 对同一张图片循环执行推理 100~1000 次。 对比每次输出结果。

预期结果:

所有推理结果完全一致。

实际结果:

输出结果存在轻微随机波动。 部分情况下会出现检测框坐标变化、置信度变化或轮廓偶发缺失。 more | 其他 | その他

通过在 src/mat.cpp 的所有 Mat::create() 重载中,对新申请的内存执行零初始化后,问题消失。

修改方式:

if (data) { memset(data, 0, totalsize);

refcount = (int*)(((unsigned char*)data) + totalsize);
*refcount = 1;

}

测试结果:

同一图片重复推理结果完全一致。 不再出现偶发轮廓丢失。 Packing、SGEMM、Winograd 等优化保持开启状态下仍可稳定复现修复效果。

怀疑根因是:

padding 区域未初始化; SIMD packing 后未被写入的 lane 保留垃圾数据; 后续算子读取了这些未定义值,从而引入随机性。

请问这是否属于已知问题?是否有更合适的修复方案(例如仅清理 padding 区域,而非整个 buffer)?