我的程序占用大部分CPU时间的部分是随后的2D循环。它的作用是使用512x512表output
填充512x512 RGB图像lut
,每个条目指向一维~4000入口RGB input
缓冲区中的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;
}
}
答案 0 :(得分:0)
您应该对input[lutv.spos0]
,input[lutv.spos1]
,input[lutv.spos2]
和input[lutv.spos3]
执行相同操作。
这些应该是指针,因为你使用对象的属性而不是对象本身。
此外,还提供了一些非常好的优化建议here。