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)?
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);
}
测试结果:
同一图片重复推理结果完全一致。
不再出现偶发轮廓丢失。
Packing、SGEMM、Winograd 等优化保持开启状态下仍可稳定复现修复效果。
怀疑根因是:
padding 区域未初始化;
SIMD packing 后未被写入的 lane 保留垃圾数据;
后续算子读取了这些未定义值,从而引入随机性。
请问这是否属于已知问题?是否有更合适的修复方案(例如仅清理 padding 区域,而非整个 buffer)?