我的程序中占用大部分 CPU 时间的部分是接下来的 2D 循环。它的作用是output
使用 512x512 表填充 512x512 RGB 图像lut
,每个条目指向一维 ~4000 条目 RGBinput
缓冲区中的 4 个条目,并指示每个输入像素的相应固定点权重。这样做的目的是将 1D 缓冲区包装到 2D 螺旋中以进行可视化,这就是它使用 LUT 的原因,因为这些索引和权重计算起来并不简单。
kV
是 512(输出图像和 LUT 的尺寸),每个结构的每个成员都是一个uint16_t
(包括.r
.g
在内.b
,lut
结构还包含两个double
值),其他值只是各种整数偏移量等等。
for (iy=0; iy<kV; iy++)
{
for (ix=0; ix<kV; ix++)
{
output[(iy+ci->vy) * ci->kW + ix+ci->vx].r = (
input[lut[iy*kV+ix].spos0].r * lut[iy*kV+ix].w0 +
input[lut[iy*kV+ix].spos1].r * lut[iy*kV+ix].w1 +
input[lut[iy*kV+ix].spos2].r * lut[iy*kV+ix].w2 +
input[lut[iy*kV+ix].spos3].r * lut[iy*kV+ix].w3) >> 15;
output[(iy+ci->vy) * ci->kW + ix+ci->vx].g = (
input[lut[iy*kV+ix].spos0].g * lut[iy*kV+ix].w0 +
input[lut[iy*kV+ix].spos1].g * lut[iy*kV+ix].w1 +
input[lut[iy*kV+ix].spos2].g * lut[iy*kV+ix].w2 +
input[lut[iy*kV+ix].spos3].g * lut[iy*kV+ix].w3) >> 15;
output[(iy+ci->vy) * ci->kW + ix+ci->vx].b = (
input[lut[iy*kV+ix].spos0].b * lut[iy*kV+ix].w0 +
input[lut[iy*kV+ix].spos1].b * lut[iy*kV+ix].w1 +
input[lut[iy*kV+ix].spos2].b * lut[iy*kV+ix].w2 +
input[lut[iy*kV+ix].spos3].b * lut[iy*kV+ix].w3) >> 15;
}
}
很简单,但我很确定有些事情做错了,或者可以更有效地完成。我为每个像素平均得到大约 66 个周期(使用 VS2010 和完全优化),考虑到这样做的简单性,我认为它可以变得更好。或不?
编辑:这是我通过建议的编辑得到的,36 个周期而不是 66 个,万岁!我们能做得更好吗?
for (iy=0; iy<kV; iy++)
{
iykv = iy*kV;
col = (iy+ci->vy) * ci->kW;
for (ix=0; ix<kV; ix++)
{
lutv = lut[iykv+ix];
outptr = &output[col + ix+ci->vx]
outptr->r = (
input[lutv.spos0].r * lutv.w0 +
input[lutv.spos1].r * lutv.w1 +
input[lutv.spos2].r * lutv.w2 +
input[lutv.spos3].r * lutv.w3) >> 15;
outptr->g = (
input[lutv.spos0].g * lutv.w0 +
input[lutv.spos1].g * lutv.w1 +
input[lutv.spos2].g * lutv.w2 +
input[lutv.spos3].g * lutv.w3) >> 15;
outptr->b = (
input[lutv.spos0].b * lutv.w0 +
input[lutv.spos1].b * lutv.w1 +
input[lutv.spos2].b * lutv.w2 +
input[lutv.spos3].b * lutv.w3) >> 15;
}
}