C++ C++;代码速度,哪个更快?

C++ C++;代码速度,哪个更快?,c++,C++,是的,这是一个家庭作业问题,我只需要朝着正确的方向努力 < C++的哪个代码块比较快,为什么?我认为它是最重要的一个,因为[I]数组正在按顺序使用,还是我错了 double A[100][100]; ... for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { A[i][j] = i * j; } } doub

是的,这是一个家庭作业问题,我只需要朝着正确的方向努力

< C++的哪个代码块比较快,为什么?我认为它是最重要的一个,因为[I]数组正在按顺序使用,还是我错了

    double A[100][100];
    ...
    for (int i = 0; i < 100; i++) {
        for (int j = 0; j < 100; j++) {
            A[i][j] = i * j;
        }
     }


    double A[100][100];
    ...
    for (int j = 0; j < 100; j++) {
    for (int i = 0; i < 100; i++) {
        A[i][j] = i * j;
    }
 }
双A[100][100];
...
对于(int i=0;i<100;i++){
对于(int j=0;j<100;j++){
A[i][j]=i*j;
}
}
双A[100][100];
...
对于(int j=0;j<100;j++){
对于(int i=0;i<100;i++){
A[i][j]=i*j;
}
}

如果不运行并分析代码,就无法知道哪段代码更快

我们可以猜测局部性和缓存行为将如何影响该时间(您的猜测是正确的),但猜测并不能代替分析。(见:)

第一个版本速度更快的一个原因是:

  • 按数组元素在内存中的排列顺序访问这些元素可以让缓存利用它们。(见:)
为什么可能没有区别:

  • 整个10000个元素都可以放入缓存中,从而使上述优化变得毫无意义

我想不出第二个会更快的原因,但我以前很惊讶。

如果不运行并分析代码,就无法知道哪段代码更快

我们可以猜测局部性和缓存行为将如何影响该时间(您的猜测是正确的),但猜测并不能代替分析。(见:)

第一个版本速度更快的一个原因是:

  • 按数组元素在内存中的排列顺序访问这些元素可以让缓存利用它们。(见:)
为什么可能没有区别:

  • 整个10000个元素都可以放入缓存中,从而使上述优化变得毫无意义

我想不出第二个会更快的原因,但我以前很惊讶。

最普遍的答案是:你需要分析这两个块,并从经验上看到结果

但是,我可以为大多数现代x86、x64、PPC和ARM处理器提供一个答案,这些处理器都具有分层缓存。在这些平台上,最上面的一个会更快,因为数据位置更好:它会按顺序访问内存地址,因此您会更频繁地访问数据缓存。智能x86和x64实现甚至会注意到您正在以这种方式顺序读取内存,并在需要下一个缓存线之前预取它。底部模式跨远程地址不连续地访问内存,这意味着每次读取时都可能丢失缓存

。他在那篇文章中的一个例子确切地说明了这两段代码是如何不同的

作为这里的数学示例,假设arguendo正在编程一个64字节缓存线大小的Intel Corei7,以及一个32kb的一级数据缓存。这意味着每次获取地址时,处理器也将获取该64字节对齐块中的所有其他数据。在那个平台上,double是8个字节,所以每个缓存线可以容纳8个字节。因此,最上面的示例将平均错过八次迭代中的一次:每次错过之后,接下来的56个字节也将被提取,因此接下来的七次double*读取将在缓存中


下面的示例可能同时将100行数据(每个
i
)放入缓存:100*64=6400字节,在缓存大小内。但也有可能超出,这意味着两条线将映射到L1中的同一SRAM,这意味着一条线将逐出另一条线。

最普遍的答案是:您需要分析两个块,并根据经验查看结果

但是,我可以为大多数现代x86、x64、PPC和ARM处理器提供一个答案,这些处理器都具有分层缓存。在这些平台上,最上面的一个会更快,因为数据位置更好:它会按顺序访问内存地址,因此您会更频繁地访问数据缓存。智能x86和x64实现甚至会注意到您正在以这种方式顺序读取内存,并在需要下一个缓存线之前预取它。底部模式跨远程地址不连续地访问内存,这意味着每次读取时都可能丢失缓存

。他在那篇文章中的一个例子确切地说明了这两段代码是如何不同的

作为这里的数学示例,假设arguendo正在编程一个64字节缓存线大小的Intel Corei7,以及一个32kb的一级数据缓存。这意味着每次获取地址时,处理器也将获取该64字节对齐块中的所有其他数据。在那个平台上,double是8个字节,所以每个缓存线可以容纳8个字节。因此,最上面的示例将平均错过八次迭代中的一次:每次错过之后,接下来的56个字节也将被提取,因此接下来的七次double*读取将在缓存中


下面的示例可能同时将100行数据(每个
i
)放入缓存:100*64=6400字节,在缓存大小内。但也有可能会超过,这意味着两条线将映射到L1中的同一SRAM,这意味着一条线将逐出另一条线。

由于可以通过整数运算将偏移量转换为
double
数组,因此无论采用哪种方式都不太重要。无论如何,编译器可能会对其进行优化。真正的问题是:当你尝试它时会发生什么?当你真正地对它进行配置时,它会运行最少的时间。你的标题是C,但是问题是C++。请修复。然后我必须解释它为什么运行faster@user1789951Ulrich Drepper的论文将教给你你需要知道的东西。由于到
double
数组的偏移量可以通过整数运算来完成,所以你用哪种方法来做并不重要。编译器将