我有一个关于std :: vector的内存行为的基本问题。我想了解为什么通过向量的简单循环比使用原始指针的相同循环要慢得多。

这是代码0:

#include<iostream>
#include<vector>
#include "utils.h" //contains Timer
using namespace std;

void ff(double * p, int n) {

  for (int i =0; i< n ; i++) p[i]+=i;

}

int main() {
  int n = 1e9;
  Timer t;  //comes from "utils.h"
  t.tic();     //start timer
  double * p = new double[n];
  ff(p, n);
  delete[] p;
  double tt = t.toc();     //stop timer
  cout << tt << endl;     // number of seconds recorded by t.
}


当我编译并运行code0时,得到以下输出:3.88309。

这是codeV:

#include<iostream>
#include<vector>
#include "utils.h"
using namespace std;

void ff(vector<double>& v, int n) {

  for (int i =0; i< n ; i++) v[i]+=i;

}

int main() {
  int n=1e9;
  Timer t;
  t.tic();
  vector<double> v(n);
  ff(v, n);
  double tt = t.toc();
  cout << tt << endl;
}


当我编译并运行codeV时,得到以下输出:5.25866。

如您所见,code0和codeV在做同样的事情,但是第一个通过指针实现,第二个通过std :: vector实现。
但是,codeV的速度几乎是code0的两倍。

让我说一下,我编译的两个代码都没有优化标志并且使用g ++。

出于好奇,我在code0和codeV上运行了valgrind和perf,结果表明:

1)codeV执行455,378,126个缓存引用,而code0仅执行185,640,714;

2)codeV在其内存调用中大约有50%的高速缓存未命中,而code0小于5%。

如果在优化标记为ON的情况下进行编译,则时间差异变小,尽管内存中的差异仍然很明显。我想问:这是怎么回事?为什么在这样一个简单的任务上std :: vector的性能比原始指针差很多?

感谢您对这个问题的任何见解!

最佳答案

没有优化,所有C ++标准库将比C代码慢。如果没有优化,所有C语言都比手写汇编要慢。你能指望什么?

为了在不进行优化的情况下使用std::vector,与C语言中的单个数组写入相比,编译器必须为写入向量元素写出大约四个函数调用。

至少使用-O2-O3 -DNDEBUG是我的偏爱。也使用-flto-fprofile-generate / -fprofile-use。查找他们。

如果您不打算快速编写C ++,为什么还要使用它呢?

关于c++ - std::vector访问内存的次数几乎是原始指针的两倍-为什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54526709/

10-11 04:51