uchar pixel; //后面省略这句for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
{
  pixel=img[i*width+j];
//省略了其它操作
}想修改以前的程序,发现这样的操作非常频繁,我想进行一些优化,以加快速度。但我看到的有书说不要进行优化,编译器会自动进行。
i*width+j有一个乘法和加法。
下面是我想的减少乘法和加法的操作,在记事本上打出来的,可能有错误。
//1:
int tempIdx;
for(int i=0;i<height;i++)
{
    tempIdx=i*width;
    for(int j=0;j<width;j++)
{
pixel=img[tempIdx+j]; }
}//2: 
int tempIdx;
for(int i=0;i<height;i++)
{
    tempIdx=i*width;
    for(int j=0;j<width;j++)
{
pixel=img[++tempIdx]; }
}//3:
int tempIdx=0;
for(int i=0;i<height;i++)
{
    for(int j=0;j<width;j++)
{
pixel=img[++tempIdx]; }
}//4:
uchar* pImg;
for(int i=0;i<height;i++)
{
    pImg=img[i*width];
    for(int j=0;j<width;j++)
{
pixel=&pImg++; }
}
//5:
uchar* pImg=img;
for(int i=0;i<height;i++)
{
    for(int j=0;j<width;j++)
{
pixel=&pImg++; }
}我的问题是
1需要优化吗?因为可读性可能会降低和引入错误。
2上面的5个都可以代替吧?
3哪种最好?
4有更好的优化方法吗?这个是最简单的情况。有些是先循环列,再循环行,有些行或列下标不是从0开始的,也不是到行尾或列尾才结束,有些循环坐标是递减的。
回复者都有分。

解决方案 »

  1.   


    都说现在的CPU对乘法进行了优化,没做过试验,也不知究竟有多大的改善?像LZ这样的例子,乘法应该都可以避免:
    int row = 0;
    for(int i = 0; i < height; ++i)
    {
        for(int j = 0; j < width; ++j)
        {
            pixel = img[row + j];
        }
        row += rowLen;
    }
      

  2.   

    如果仅仅是遍历,还可以int length = height*width;
    for(int i = 0; i < length ; ++i)
    {
        pixel = img[i];
    }如果循环中要使用到i和j值,那其实第一种方法就可以了。
    总的来说,楼主优化的目的是什么的?如果是程序运行缓慢,那缓慢的根源是这些循环吗?
      

  3.   

    我现在程序要识别90帧每秒的图像。开始时最花时间的是分配和释放内存,我把内存一次性分配玩,程序退出后再释放。现在cpu占用率仍然高,把其中一个核心占满了。我觉得最花时间的是这些简单的循环里的乘法,但这仅仅是猜测。所以想优化这个地方,从汇编优化我还未达到这样的水平。程序的debug和release速度差别不大,我觉得编译器没做多少优化。
      

  4.   

    5个的区别其实都不大,循环已经没有什么优化的余地了,高速图像处理的关键在于运用SSE指令集
      

  5.   


    正解。现在的编译器对付楼主这种循环已经游刃有余了,编译时加上SSE指令选项即可,速度可以提升很多。
      

  6.   

    优化的程度依赖于编译器。具体的作用还是得实测才知道。lz可以看看编译器生成的这部分循环的汇编代码,看是否有重复计算,按说应该是没有的。真正要优化,还是得靠向量化,SSE,SSE2,SSE3啥的