循环展开C ++中的像素

时间:2015-04-24 10:10:03

标签: c++ performance pixels

我有一个相对较大的循环,并希望展开它以加快我的应用程序。代码是:

byte* oRow = (byte*)bitmapData1.Scan0 + (y * bitmapData1.Stride);
        for (UINT x = 0; x < 4000; ++x)
        {
            #pragma unroll
            byte grey = (
                (oRow[x + x + x] * 114) + //B
                (oRow[x + x + x + 1] * 587) +  //G
                (oRow[x + x + x + 2] * 299)) / 1000; //R

            fl_x = floor(x + x);
            fl_y = floor(y + y);

            cl_x = fl_x + 1;
            if (cl_x >= 4752)
                cl_x = fl_x;

            cl_y = fl_y + 1;
            if (cl_y >= 3168)
                cl_y = fl_y;

            fractionX = x + x - fl_x;
            fractionY = y + y - fl_y;
            oneMinusX = 1.0 - fractionX;
            oneMinusY = 1.0 - fractionY;

            b1 = oneMinusX * grey + fractionX * grey;
            b2 = oneMinusX * grey + fractionX * grey;
            blue = oneMinusY * (b1)+fractionY * (b2);

            b1 = oneMinusX * grey + fractionX * grey;
            b2 = oneMinusX * grey + fractionX * grey;
            green = oneMinusY * (b1)+fractionY * (b2);

            b1 = oneMinusX * grey + fractionX * grey;
            b2 = oneMinusX * grey + fractionX *grey;
            red = oneMinusY * (b1)+fractionY * (b2);

            oRow[x + x + x] = blue;
            oRow[x + x + x + 1] = green;
            oRow[x + x + x + 2] = red;
       }

我尝试通过将循环计数器更改为

来展开它
for (UINT x = 0; x < 2000; x+=2)

并在重复代码之前将x添加到x,但它运行不正常

2 个答案:

答案 0 :(得分:4)

  

我尝试通过将循环计数器更改为

来展开它      

for (UINT x = 0; x < 2000; x+=2)

     

并在重复代码之前将x添加到x,但它运行不正常

循环展开的逻辑是有缺陷的。您需要在每次迭代时处理xx + 1的元素,而不是xx + 2000,并且上限仍然是4000:

for (UINT x = 0; x < 4000; x+=2)
{
    // do stuff for element x
    // ...

    // do stuff for element x + 1
    // ...
}

正如已经注意到的那样,你可能会浪费你的时间。编译器非常擅长在需要时展开代码,手动循环展开甚至可以在现代CPU上适得其反。

专业提示:确保您正在编译并启用所有优化功能(例如gcc -O3 ...),并对您的代码进行分析,以确保此循环确实需要优化。如果您确定需要优化此代码,那么在使用循环展开之前,您可以使用一些非常明显的低效率。

答案 1 :(得分:1)

for (UINT x = 0; x < 2000; x+=2)

将循环1000个值:0,2,4 ... 1998

这可能不是你想要的。你要么

for (UINT x = 0; x < 2000; x+=1) // values 0, 1, ... 1999

for (UINT x = 0; x < 4000; x+=2) // values 0, 2, ... 3998