I have a rather basic question about the memory behavior of std::vector. I would like to understand why a simple loop through a vector is much slower than the same loop using a raw pointer.
This is code0:
#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.
}
When I compile and run code0 I get the following output: 3.88309.
This is 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;
}
When I compile and run codeV I get the following output: 5.25866.
As you can see, code0 and codeV are doing the same thing, but the first is implemented with pointer and the second with std::vector. However codeV is almost twice as slow as code0.
Let me remark that I compiled both codes without optimization flags and using g++.
Out of curiosity I ran valgrind and perf on code0 and codeV, and it turns out that:
1) codeV performs 455,378,126 cache references, while code0 only 185,640,714;
2) codeV has about 50% cache misses among its memory calls, while code0 less than 5%.
If compiled with optimization flags on, the difference in time become less marked, though those on memory are still noticeable. I would like to ask: what is going on ? Why is std::vector performing so much worse than a raw pointer on such a simple task?
Thank you for any insight on this issue!