【问题标题】:How long does it take a for loop to get started?开始for循环需要多长时间?
【发布时间】:2015-09-12 06:51:05
【问题描述】:

我正在用 C++ 编写代码,我可以选择运行 1 个 for 循环和 4 个加法操作,或者运行 4 个单独的 for 循环,每个循环都有 1 个加法操作。 (作为旁注,我正在考虑这个问题,因为 4-loops-1-addition 意味着我在我正在编写的程序中分配了 1/4 的内存)

本能地我希望 1-loop-4-additions 更快,我做了一个快速的基准测试来证明这一点。 1-loop-4-addition 的时间大约是 4-loops-1-addition 的一半

我的问题:正在发生什么过程来产生这种差异?

以下是我用于测试的代码 - 我是数学家而不是程序员,所以我很可能会做一些愚蠢的事情。我正在使用 2D 数组,因为这就是我正在编码的内容。

#include <stdio.h>
#include <ctime>
#include <iostream>

using namespace std;

int main(){
    int Nx=100;
    int Ny=Nx;
    double holder=0;

    double test[Nx][Ny];
    double test1[Nx][Ny];
    double test2[Nx][Ny];
    double test3[Nx][Ny];
    double test4[Nx][Ny];

    for(int i=0;i<Nx;i++){
        for(int j=0;j<Nx;j++){
            test[i][j]=1;
            test1[i][j]=1;
            test2[i][j]=1;
            test3[i][j]=1;
            test4[i][j]=1;
        }
    }
    clock_t begin= clock();
    for(int i=0;i<Nx;i++){
        for(int j=0;j<Ny;j++){
            holder=holder + test[i][j];
        }
    }
    for(int i=0;i<Nx;i++){
        for(int j=0;j<Ny;j++){
            holder=holder + test[i][j];
        }
    }
    for(int i=0;i<Nx;i++){
        for(int j=0;j<Ny;j++){
            holder=holder + test[i][j];
        }
    }
    for(int i=0;i<Nx;i++){
        for(int j=0;j<Ny;j++){
            holder=holder + test[i][j];
        }
    }
    clock_t end = clock();
    double elapsed = (double) (end-begin)/CLOCKS_PER_SEC;

    cout<<"Time to run 1 addition in 4 for loops="<<elapsed<<endl;

    begin= clock();
    for(int i=0;i<Nx;i++){
        for(int j=0;j<Ny;j++){
            holder=holder + test1[i][j]+ test2[i][j]+ test3[i][j]+ test4[i][j];
        }
    }
    end = clock();
    elapsed = (double) (end-begin)/CLOCKS_PER_SEC;

    cout<<"Time to run 4 additions in 1 for loop="<<elapsed<<endl;
}

【问题讨论】:

  • "我正在用 C 编写代码" -- 但我看到的是 C++ 代码。
  • 100 次迭代你根本看不到任何差异。
  • 最明显的区别是比较的次数。考虑一下j &lt; Ny 在每种情况下总共运行了多少次。
  • 嗯,你在分析优化代码吗?每个 C 编译器都知道如何展开循环,手动展开是不必要的。并且每个 C 编译器都可以生成一个汇编列表,看看。
  • @e4c5 它是 100x100 次迭代 - 当我在计算机上运行它时,我不得不将它限制在这个数字上,以避免 seg 错误@HansPassant 正如我所说,我不是程序员,但是当我用 clang++ 编译它时,我确实有 -o 标志

标签: c++ performance for-loop


【解决方案1】:

使用第一个选项,您正在执行 4*(NxNy) 操作,而使用第二个选项,您正在执行 NxNy 操作,因此对于较大的 Nx,Ny,第二个循环完成得更快是正常的

【讨论】:

  • 如果您只讨论操作,这两种方法执行相同数量的操作。说话asymptotically 是另一回事。
【解决方案2】:

让我们仔细看看这两个循环,看看发生了什么。如果仔细观察,二维数组的addition 操作数是相同的。但是,两种方法中进行i&lt;Nxj&lt;Ny 等比较的次数以及ij 的增量是不同的。在 1st 方法中是 4 倍。

这可能是这两种方法执行时间较长的原因之一。

【讨论】:

  • 谢谢,我什至没有想到这一点。还会发生什么其他事情?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2019-07-21
  • 2019-09-03
相关资源
最近更新 更多