问题描述
似乎有一种观点认为在 64 位架构上不需要使用拆分堆栈"运行时模型.我说似乎是,因为我还没有看到有人真的这么说,只能绕着它跳舞:
There seems to be an opinion out there that using a "split stack" runtime model is unnecessary on 64-bit architectures. I say seems to be, because I haven't seen anyone actually say that, only dance around it:
典型的多线程程序的内存使用可以减少重要的是,因为每个线程不需要最坏情况的堆栈尺寸.可以运行数百万个线程(完整的 NPTL线程或协同程序)在 32 位地址空间中.-- 伊恩·兰斯·泰勒
...暗示 64 位地址空间已经可以处理它.
...implying that a 64-bit address space can already handle it.
还有……
... 拆分堆栈的持续开销和狭窄的用例(在 32 位架构上产生大量 I/O 绑定任务)不能接受...-- bstrie
两个问题:这是他们所说的吗?其次,如果是这样,为什么它们在 64 位架构上是不必要的?
Two questions: Is this what they are saying? Second, if so, why are they unneccesary on 64-bit architectures?
推荐答案
是的,他们就是这么说的.
Yes, that's what they are saying.
在 64 位架构上(目前)不需要拆分堆栈,因为 64 位虚拟地址空间非常大,可以包含数百万个堆栈地址范围,如果需要,每个地址范围都相当于整个 32 位地址空间.
Split stacks are (currently) unnecessary on 64bit architectures because the 64bit virtual address space is so large it can contain millions of stack address ranges, each as large as an entire 32bit address space, if needed.
在当今使用的平面内存模型中,从虚拟地址到物理内存位置的转换是在支持下完成的硬件 MMU.在 amd64 上,结果证明保留大块 64 位虚拟地址更好(意味着总体上更快)您正在创建的每个新堆栈的空间,而只将第一页 (4kB) 映射到实际 RAM.这样,堆栈将能够根据需要在连续的虚拟地址上增长和缩小(意味着每个函数序言,一个很大的优化)而操作系统重新配置 MMU 以将每个虚拟地址页面映射到 RAM 的实际空闲页面,每当堆栈增长或缩小到高于/低于某些可配置阈值时.
通过巧妙地选择阈值(参见例如动态数组的理论),您可以实现 O(1) 复杂度在平均堆栈操作上,同时保留数百万个堆栈的好处,这些堆栈可以根据需要增长,并且只消耗它们使用的内存.
By choosing the thresholds smartly (see for example the theory of dynamic arrays) you can achieve O(1) complexity on the average stack operation, while retaining the benefits of millions of stacks that can grow as much as you need and only consume the memory they use.
PS:当前的 Go 实现远远落后于此 :-)
PS: the current Go implementation is far behind any of this :-)
这篇关于在 amd64 上拆分堆栈是不必要的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!