优化基于表的插值循环

时间:2013-09-14 18:09:09

标签: c graphics interpolation lookup-tables

我的程序占用大部分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;
        }
    }

1 个答案:

答案 0 :(得分:0)

您应该对input[lutv.spos0]input[lutv.spos1]input[lutv.spos2]input[lutv.spos3]执行相同操作。

这些应该是指针,因为你使用对象的属性而不是对象本身。

此外,还提供了一些非常好的优化建议here