我知道局部变量将按顺序存储在堆栈中。
但是,当我在c++中动态分配堆内存中的变量时,就像这样。
int * a = new int{1};
int * a2 = new int{2};
int * a3 = new int{3};
int * a4 = new int{4};问题1:这些变量是否存储在连续的内存位置?问题2:如果不是,是因为动态分配将变量存储在堆内存中的随机位置吗?Question3 :那么动态分配是否会增加缓存未命中的可能性,并具有低空间局部性?
发布于 2019-03-16 16:34:10
第1部分:单独分配是连续的吗?
答案可能不是,而是。动态分配的发生方式取决于实现。如果您像上面的例子那样分配内存,两个单独的分配可能是连续的,但不能保证会发生这种情况(而且不应该依赖它)。
c++的不同实现使用不同的算法来决定如何分配内存。
第2部分:分配是随机的吗?
内存不是以故意随机的方式分配的。内存分配器通常会尝试分配彼此附近的内存块,以最小化页面错误和缓存未命中,但并不总是可以做到这一点。
分配分两个阶段进行:
在第二个阶段,实现可以尝试为您提供接近其他最近分配的内存,但是它对第一阶段几乎没有控制(操作系统通常只提供任何可用的内存,而不知道您的程序所分配的其他内存)。
第3部分:避免缓存未命中
如果缓存未命中是代码中瓶颈,
一个很好的通用原则是只使用对象的std::vector,除非你有很好的理由使用更花哨的东西。因为它们具有更好的缓存局部性,所以在插入和删除元素时,std::vector比std::list更快,甚至可以插入和删除数十个甚至数百个元素。
最后:试着利用堆栈。除非有很好的理由让某些东西成为指针,否则只需声明为堆栈上的变量即可。如果可能的话,
MyClass x{};而不是MyClass* x = new MyClass{};,std::vector<MyClass>而不是std::vector<MyClass*>。通过扩展,如果您可以使用静态多态性(即,模板),请使用它而不是动态多态性。
发布于 2019-03-16 16:52:58
IMHO这是操作系统特定的/ C++标准库实现。
new最终使用较低级别的虚拟内存分配服务,并使用mmap和munmap等系统调用一次分配多个页面。new的实现可以在相关情况下重用先前释放的内存空间。new的实现可以对“大”和“小”分配使用各种不同的策略。
在为内存分配(通常是几个页面)的系统调用中提供第一个new结果的示例中,分配的内存可能足够大,因此后续的new调用会产生连续的allocation..But,这取决于实现
发布于 2019-03-16 17:07:18
简而言之:
https://stackoverflow.com/questions/55194751
复制相似问题