gpt4 book ai didi

c++ - std::vector 访问内存的次数几乎是原始指针的两倍——为什么?

转载 作者:行者123 更新时间:2023-11-28 01:24:34 25 4
gpt4 key购买 nike

我有一个关于 std::vector 的内存行为的相当基本的问题。我想了解为什么通过 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。

这是代码V:

#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%。

如果在启用优化标志的情况下编译,时间差异会变得不那么明显,但内存上的差异仍然很明显。请问:这是怎么回事?为什么 std::vector 在如此简单的任务上的表现比原始指针差这么多?

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

最佳答案

如果不进行优化,所有的 C++ 标准库都会比 C 代码慢。没有优化,所有的 C 都比手写汇编慢。你期待什么?

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

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

如果您编写 C++ 不是为了速度快,为什么还要使用它?

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com