如果内部的总工作量相同,那么将for循环拆分成多个for循环的开销是多少?

And*_*ong 7 c++ performance for-loop

分割for像这样的循环的开销是多少,

int i;

for (i = 0; i < exchanges; i++)
{
    // some code
    // some more code
    // even more code
}
Run Code Online (Sandbox Code Playgroud)

分成这样的多个for循环?

int i;

for (i = 0; i < exchanges; i++)
{
    // some code
}

for (i = 0; i < exchanges; i++)
{
    // some more code
}

for (i = 0; i < exchanges; i++)
{
    // even more code
}
Run Code Online (Sandbox Code Playgroud)

该代码性能敏感的,但这样做后者将提高可读性显著.(如果重要的话,在每个循环中没有其他循环,变量声明或函数调用,除少数访问器外.)

我不是一个低级别的编程大师,所以如果有人能够衡量与基本操作相比的性能损失,那就更好了,例如 "每个额外的for循环将花费相当于两个int分配." 但是,如果不是那么简单,我理解(并且不会感到惊讶).

提前谢谢了.

Mys*_*ial 12

通常会有太多因素在起作用......并且很容易证明两种方式:

例如,拆分以下循环导致差不多2倍的速度减慢(底部的完整测试代码):

for (int c = 0; c < size; c++){
    data[c] *= 10;
    data[c] += 7;
    data[c] &= 15;
}
Run Code Online (Sandbox Code Playgroud)

这几乎是明显的,因为你需要循环3次而不是一次,你在整个数组上进行3遍而不是1次.

另一方面,如果你看一下这个问题:为什么在单独的循环中元素加法比在组合循环中加快得多?

for(int j=0;j<n;j++){
    a1[j] += b1[j];
    c1[j] += d1[j];
}
Run Code Online (Sandbox Code Playgroud)

由于存储器对齐,相反的情况有时是正确的.


从这里拿走什么?

几乎任何事都可能发生.这两种方式总是更快,并且很大程度上取决于循环内部的内容.

因此,确定这样的优化是否会提高性能通常是反复试验.有了足够的经验,你可以做出相当自信(受过教育的)猜测.但总的来说,期待任何事情.

"每个额外的for循环将花费相当于两个int分配."

你说的不是那么简单.实际上它太复杂了,数字并不重要.循环迭代可以在一个上下文中进行X个循环,但是由于诸如无序执行和数据依赖性之类的多种因素,Y循环在另一个上下文中.

不仅性能依赖于上下文,而且它随着不同的处理器而变化.


这是测试代码:

#include <time.h>
#include <iostream>
using namespace std;

int main(){

    int size = 10000;
    int *data = new int[size];


    clock_t start = clock();

    for (int i = 0; i < 1000000; i++){
#ifdef TOGETHER
        for (int c = 0; c < size; c++){
            data[c] *= 10;
            data[c] += 7;
            data[c] &= 15;
        }
#else
        for (int c = 0; c < size; c++){
            data[c] *= 10;
        }
        for (int c = 0; c < size; c++){
            data[c] += 7;
        }
        for (int c = 0; c < size; c++){
            data[c] &= 15;
        }
#endif
    }

    clock_t end = clock();
    cout << (double)(end - start) / CLOCKS_PER_SEC << endl;

    system("pause");
}
Run Code Online (Sandbox Code Playgroud)

输出(一个循环): 4.08秒
输出(3个循环): 7.17秒