在 amd64 上拆分堆栈是不必要的 [英] Split stacks unneccesary on amd64

查看:31
本文介绍了在 amd64 上拆分堆栈是不必要的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎有一种观点认为在 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 位地址空间中.-- 伊恩·兰斯·泰勒

The memory usage of a typical multi-threaded program can decrease significantly, as each thread does not require a worst-case stack size. It becomes possible to run millions of threads (either full NPTL threads or co-routines) in a 32-bit address space. -- Ian Lance Taylor

...暗示 64 位地址空间已经可以处理它.

...implying that a 64-bit address space can already handle it.

还有……

... 拆分堆栈的持续开销和狭窄的用例(在 32 位架构上产生大量 I/O 绑定任务)不能接受...-- bstrie

... the constant overhead of split stacks and the narrow use case (spawning enormous numbers of I/O-bound tasks on 32-bit architectures) isn't acceptable... -- 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 的实际空闲页面,每当堆栈增长或缩小到高于/低于某些可配置阈值时.

In the Flat memory model in use nowadays, the translation from virtual addresses to phisical memory locations is done with the support of the hardware MMU. On amd64 it turns out it's better (meaning, overall faster) to reserve big chunks of the 64bit virtual address space to each new stack you are creating, while only mapping the first page (4kB) to actual RAM. This way, the stack will be able to grow and shrink as needed, over contiguous virtual addresses (meaning less code in each function prologue, a big optimization) while the OS re-configures the MMU to map each page of virtual addresses to an actual free page of RAM, whenever the stack grows or shrinks above/below some configurable thresholds.

通过巧妙地选择阈值(参见例如动态数组的理论),您可以实现 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 上拆分堆栈是不必要的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆