我知道局部变量将有序地存储在堆栈中。
但是,当我像这样用c ++在堆内存中动态分配变量时。
int * a = new int{1};
int * a2 = new int{2};
int * a3 = new int{3};
int * a4 = new int{4};
问题1:这些变量是否存储在连续的内存位置中? 问题2:是否不是因为动态分配将变量存储在堆内存中的随机位置? 问题3:动态分配会增加高速缓存未命中的可能性并降低空间局部性吗?
答案 0 :(得分:1)
答案是可能不是。动态分配如何发生取决于实现。如果像上面的示例一样分配内存,则两个单独的分配可能是连续的,但是不能保证会发生这种情况(并且永远不应依赖于这种情况)。
c ++的不同实现使用不同的算法来决定如何分配内存。
有点;但并非完全如此。内存不会以故意随机的方式分配。通常,内存分配器会尝试将彼此相邻的内存块分配在一起,以最大程度地减少页面错误和高速缓存未命中,但并非总是可以这样做。
分配过程分为两个阶段:
在第二阶段,实现可以尝试为您提供接近其他最近分配的内存,但是它对第一阶段几乎没有控制(并且操作系统通常仅提供可用的任何内存,而无需其他任何知识由您的程序分配)。
如果高速缓存未命中是代码中的瓶颈,则
一个好的通用原则是只使用对象的std :: vector,除非您有充分的理由使用更高级的东西。因为它们具有更好的缓存局部性,所以std :: vector在插入和删除元素方面比std :: list更快,甚至多达数十甚至数百个元素。
最后:尝试利用堆栈。除非有充分的理由使某个东西成为指针,否则只需声明为存在于堆栈中的变量即可。
MyClass x{};
代替MyClass* x = new MyClass{};
,并且std::vector<MyClass>
而不是std::vector<MyClass*>
。 通过扩展,如果可以使用静态多态性(即模板),请使用它代替动态多态性。
答案 1 :(得分:0)
恕我直言,这是特定于操作系统/ C ++标准库的实现。
<script type="text/javascript">
var map; // declare as global
function initMap() {
var uluru = {lat: 37.7749, lng: -122.4194};
//\/ --- initialize the global `map` variable (don't create a new local map variable)
map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
// standard google map javascript
} //end of initMap()
$('#id_zoomlevel').on('change', function() {
var zoomlevel = $('#id\_zoomlevel :selected').attr('value');
map.setZoom(zoomlevel);
});
</script>
最终使用较低级别的虚拟内存分配服务,并通过mmap和munmap之类的系统调用一次分配多个页面。 new
的实现可以在相关时重用以前释放的内存空间。
new
的实现可以对“大”和“小”分配使用各种不同的策略。
在该示例中,您给系统的第一个new
结果用于内存分配(通常是几页),分配的内存可能足够大,因此后续的new
调用会导致连续分配。 。但这取决于实现方式
答案 2 :(得分:0)
简而言之:
一点都不(由于对齐,堆管理数据,分配的块可能被重用等导致填充),
一点也不(AFAIK,堆算法是确定性的,没有任何随机性),
通常是(例如,内存池可能对此有所帮助)。