<p>一维指针遍历图像比二维索引更高效,因内存本为行优先一维布局;用BYTE pCur=pImg和pEnd=pImg+widthheight进行单指针遍历,避免y*width+x重复计算,提升CPU缓存命中与编译器优化。</p>

直接用连续内存块操作图像,是加速最基础也最有效的手段。关键不是“能不能做”,而是“怎么组织数据、怎么访问它”——数组缓冲区本身不加速,但用对了方式,就能让CPU缓存、指针运算、并行调度全部跑起来。
用一维指针代替二维索引
图像在内存里本就是一维排列(行优先),却常被写成 pImg[y][x]。这看似直观,实际每次访问都要算 y * width + x,多一次乘法、两次加法,还容易让编译器无法优化循环。更高效的方式是用单指针遍历:
- 定义 BYTE* pCur = pImg,BYTE* pEnd = pImg + width * height
- 用 for (; pCur 遍历,*pCur 就是当前像素值
- 结果写入也同步递增指针:*(pRes++) = f(*pCur)
预分配+零拷贝的缓冲区管理
频繁 malloc/free 或 memcpy 是隐性性能杀手。RMBG-2.0 实践中发现,预处理阶段近 60% 时间花在数据搬运上。解决办法是统一申请一块大缓冲区,按需切片复用:
- 一次性分配 uint8_t* buffer = malloc(width * height * 4)(含 Alpha 通道)
- 把解码输出、归一化中间值、模型输入 float 数组,都映射到这块内存的不同偏移处
- 避免逐像素类型转换:用 SIMD 批量转 float,或直接用 __builtin_assume_aligned 告诉编译器地址对齐
对齐访问 + 缓存友好布局
CPU 缓存按行填充(典型 64 字节 cache line),若访问模式跳着走,就会反复换行,造成大量 cache miss。灰度化、滤波这类操作必须保证:
- 按行顺序访问:外层循环 y,内层 x,且 x 步进为 1
- 图像宽度尽量是 16/32 的倍数(适配 AVX2/NEON 寄存器宽度)
- 若做跨通道计算(如 RGB→Gray),把 R/G/B 分量连续存放(planar 格式反而不利),推荐 interleaved 布局:[R0,G0,B0,R1,G1,B1,...]
结合硬件向量化扩展
有了连续缓冲区,才能真正发挥 SIMD 指令威力。例如 Java Vector API 或 C 的 intrinsics 要求数据对齐、长度可控:
- 用 FloatVector.fromArray(species, pixels, i) 一次加载 8 个 float 像素
- C 中调用 _mm256_load_ps(ptr) 前,确保 ptr 是 32 字节对齐
- 边界处理单独写一段标量逻辑,主体循环全用向量指令,实测灰度化提速 3 倍以上

















