指针向量与值向量 大内存块与小内存块的性能损失
Vector of pointers vs vector of values performance penalty for large vs small memory blocks
我执行了一个小型测试来确定访问指针向量与值向量的行为。事实证明,对于小内存块,两者的性能相同,但是,对于大内存块,存在显着差异。
这种行为的解释是什么?
对于在我的电脑上执行的以下代码,D=0 的差异约为 35%,而 D=10 的差异并不明显。
int D = 0;
int K = 1 << (22 - D);
int J = 100 * (1 << D);
int sum = 0;
std::vector<int> a(K);
std::iota(a.begin(), a.end(), 0);
long start = clock();
for (int j = 0; j < J; ++j)
for (int i = 0; i < a.size(); ++i)
sum += a[i];
std::cout << double(clock() - start) / CLOCKS_PER_SEC << " " << sum << std::endl;
sum = 0;
std::vector<int*> b(a.size());
for (int i = 0; i < a.size(); ++i) b[i] = &a[i];
start = clock();
for (int j = 0; j < J; ++j)
for (int i = 0; i < b.size(); ++i)
sum += *b[i];
std::cout << double(clock() - start) / CLOCKS_PER_SEC << " " << sum << std::endl;
从全局内存获取数据很慢,因此 CPU 有一小部分非常快的内存来帮助内存访问跟上处理器的步伐。在处理内存请求时,您的计算机将尝试加快对内存中单个整数或指针的未来请求,方法是在您请求的位置周围请求一大堆整数或指针并将它们存储在缓存中。一旦快速内存已满,每当请求新内容时,都必须摆脱其最不喜欢的位。
您的小问题可能完全或基本上适合缓存,因此内存访问速度非常快。大问题无法容纳在这么快的内存中,所以你有问题。向量存储为 K 个连续的内存位置。当你访问一个向量时int
它会加载 int 和他附近的一些值,这些值可以立即使用。但是,当您加载int*
时,它会加载指向实际值的指针以及其他几个指针。这会占用一些内存。然后,当您取消引用时*
它会加载实际值,并可能加载附近的一些实际值。 这会占用更多内存。您不仅必须执行更多工作,而且还要更快地填满内存。时间的实际增加会有所不同,因为它高度依赖于体系结构、操作(在本例中为 +
)和内存速度。此外,您的编译器将非常努力地工作以最大程度地减少延迟。
相关文章:
- 迭代时从向量和内存中删除对象
- 我在二维向量中是否正确分配了内存
- 字符串共享内存映射的向量
- 具有 STL 向量类型成员的类的复制内存
- 重新分配向量时,向量中的内存会发生什么情况
- 向量的内存位置不连续
- 自己的自定义向量类. 内存重新分配
- 分配具有 2D 向量大小的变量的内存
- 在统一内存 CUDA C/C++ 中分配 2D 向量
- 将 c++ 向量转换为字符 ** 而不会泄漏内存
- 大向量和内存守恒c++
- 如果不初始化结构中的向量,它会自动为空还是具有随机内存位置的值?
- 从函数内对象的向量中释放内存
- 使用pushback分配内存与构造特定大小的向量
- 结构向量中自定义结构函数的内存使用
- 故意泄漏std::向量的内存
- 释放包含多个向量的结构的内存
- 字符串的内存高效向量
- C++ STL 向量保留太多容量会消耗大量内存吗?
- VS2012静态代码分析器在取消分配内存向量时给出误报