Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ErasoStIES C++代码的筛选器在连续运行中加速了——为什么?_C++_Performance_Cpu - Fatal编程技术网

ErasoStIES C++代码的筛选器在连续运行中加速了——为什么?

ErasoStIES C++代码的筛选器在连续运行中加速了——为什么?,c++,performance,cpu,C++,Performance,Cpu,我快速查看了一下这个问题,但找不到答案——尽管我猜它可能是以前在这里提出来的 我在写一个C++中的ErasoStEes筛选器的简单实现,然后给出结果: #include <iostream> #include <math.h> int main() { int n = 100000; int seive [n]; for (int i=0; i<n; i++) { seive[i] = i; } for (int i=2; i

我快速查看了一下这个问题,但找不到答案——尽管我猜它可能是以前在这里提出来的

我在写一个C++中的ErasoStEes筛选器的简单实现,然后给出结果:

#include <iostream> 
#include <math.h>


int main() {

  int n = 100000;
  int seive [n];

  for (int i=0; i<n; i++) {
    seive[i] = i;
  }

  for (int i=2; i < ceil(sqrt(n)); i++) {
    for (int j=i*2; j<=n; j+=i) {
      seive[j-1] = -9;
    }
  }

  for (int i=0; i<n; i++) {
    if (seive[i] != -9) {
      std::cout << i+1 << "\n";
    }
  }

  return 0;
}
然后使用以下方法计时:

g++ seive.cpp -o seiveCpp
time ./seiveCpp
第一次:

./seiveCpp  0.01s user 0.01s system 10% cpu 0.184 total
第二次:

./seiveCpp  0.01s user 0.01s system 58% cpu 0.034 total
第三次:

./seiveCpp  0.01s user 0.01s system 59% cpu 0.037 total
等等

如果我重复多次,第一次运行代码的速度似乎总是比所有连续运行的时间慢5倍左右

这背后的原因是什么


我在2017 MacBook Pro、2.3 GHz双核Intel Core i5上运行此程序,并使用Apple clang 11.0.0 clang-1100.0.33.12版编译。原因在于分支预测器。第一次运行时,计算机对程序一无所知,但在执行程序时,它会在代码的跳转中找到逻辑,if和then可以更好地预测它应该采用哪个分支。在现代处理器中,有很长的命令管道,因此正确预测跳转可以显著减少工作时间


因此,通过执行时间来比较几种算法,最好是运行100次并占用最少的时间

原因在于分支预测器。第一次运行时,计算机对程序一无所知,但在执行程序时,它会在代码的跳转中找到逻辑,if和then可以更好地预测它应该采用哪个分支。在现代处理器中,有很长的命令管道,因此正确预测跳转可以显著减少工作时间


因此,通过执行时间来比较几种算法,最好是运行100次并占用最少的时间

考虑到非常大的差异,我猜当您开始第一次运行时,CPU处于较低的性能模式,但在第一次运行的负载下,操作系统将其切换到较高的性能模式,您会发现这是较低的执行时间

确保您的笔记本电脑已连接到交流电源,并且如果要避免这种影响,请禁用所有节能选项

在任何情况下,仍然会留下缓存效果,例如,可执行文件中的内容可能会缓存在内存中。但我认为这些不应该是100毫秒左右


一般来说,当您对代码进行基准测试时,您应该始终进行预热运行,因为在某种程度上,由于某种原因,总会有这样的影响。一般来说,您希望在环境达到平衡状态时执行实际的测试运行。

考虑到非常大的差异,我猜当您开始第一次运行时,CPU处于较低的性能模式,但在第一次运行的负载下,操作系统将其切换到较高的性能模式,您观察到执行时间缩短了

确保您的笔记本电脑已连接到交流电源,并且如果要避免这种影响,请禁用所有节能选项

在任何情况下,仍然会留下缓存效果,例如,可执行文件中的内容可能会缓存在内存中。但我认为这些不应该是100毫秒左右


一般来说,当您对代码进行基准测试时,您应该始终进行预热运行,因为在某种程度上,由于某种原因,总会有这样的影响。一般来说,您希望在环境达到平衡状态时执行实际测试运行。

当操作系统第一次必须将文件加载到内存时多次运行程序,下一次可能已经存在该文件,尽管根据编译器/链接器的设置可能仍需要重新定位,即是否生成位置独立代码。如果您在单个进程中多次运行同一代码,分支位置答案将更有可能适用,这在收集性能数据时是一个好主意-将计时代码放入程序中,并多次运行感兴趣的代码,为每个循环计时,而不是使用外部计时程序多次运行整个程序。

当操作系统第一次必须将文件加载到内存中时,程序多次运行时,下一次可能已经存在,尽管根据编译器/链接器的设置可能仍需要重新定位,即是否生成位置独立代码。如果您在单个进程中多次运行同一代码,分支位置答案将更有可能适用,这在收集性能数据时是一个好主意-将计时代码放入程序中,并多次运行感兴趣的代码,为每个循环计时,而不是多次运行整个程序并使用外部计时程序。

int seive[n];-这不是C++。C++中的数组必须具有由编译时Excel表示的大小。
session,而不是运行时变量或表达式,如n。使用std::vector seiven;相反,如果您正在对您的程序进行基准测试,那么启用优化将是一个好主意。尝试添加-O2或-O3选项标志。您测量筛网性能的机制不合适。最大的影响是,你的时间安排显然包括了所有素数的成本。连接到控制台是非常昂贵的。您可以将输出重定向到文件。您可能会将结果保存到内存中,也许是stringstream?,然后在计时器停止后将其保存。事实上,我并不担心这段特定代码的性能—我只是碰巧对其计时,并注意到它在第二次运行时总是比较慢。这更像是一个通过这个例子说明的一般性问题。也许你什么都没学到,因为到终端的cout是非常可变的,而且通常很慢。也许你太依赖、太相信“时间”这个实用工具的使用了这不是C++。C++中的数组必须用编译时表达式表示它们的大小,而不是运行时变量或表达式,如N。使用std::vector seiven;相反,如果您正在对您的程序进行基准测试,那么启用优化将是一个好主意。尝试添加-O2或-O3选项标志。您测量筛网性能的机制不合适。最大的影响是,你的时间安排显然包括了所有素数的成本。连接到控制台是非常昂贵的。您可以将输出重定向到文件。您可能会将结果保存到内存中,也许是stringstream?,然后在计时器停止后将其保存。事实上,我并不担心这段特定代码的性能—我只是碰巧对其计时,并注意到它在第二次运行时总是比较慢。这更像是一个通过这个例子说明的一般性问题。也许你什么都没学到,因为到终端的cout是非常可变的,而且通常很慢。也许你太依赖,太相信“时间”效用的使用。