multithreading - 在 amd64 上拆分堆栈是不必要的

标签 multithreading go 64-bit callstack rust

似乎有一种观点认为,在 64 位架构上没有必要使用“拆分堆栈”运行时模型。我说好像是,因为我还没有看到有人真的这么说,只是围着它跳舞:

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 位地址空间已经可以处理它。

还有……

... 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 位架构上是不必要的?

最佳答案

是的,他们就是这么说的。

在 64 位架构上(目前)不需要拆分堆栈,因为 64 位虚拟地址空间非常大,可以包含数百万个堆栈地址范围,如果需要,每个堆栈地址范围都与整个 32 位地址空间一样大。

Flat memory model现在使用,从虚拟地址到物理内存位置的转换是在 hardware MMU 的支持下完成的。 .在 amd64事实证明,将大块 64 位虚拟地址空间保留给您正在创建的每个新堆栈,同时仅将第一页 (4kB) 映射到实际 RAM 会更好(这意味着总体上更快)。这样,当操作系统重新配置 MMU 以将虚拟地址的每一页映射到一个实际可用的 RAM 页面,无论何时堆栈增长或缩小高于/低于某些可配置的阈值。

通过巧妙地选择阈值(例如,参见 function prologue 的理论),您可以在平均堆栈操作上实现 O(1) 复杂度,同时保留数百万堆栈的好处,这些堆栈可以根据您的需要增长,并且只消耗他们使用的内存。

PS:当前的 Go 实现远远落后于任何一个 :-)

关于multithreading - 在 amd64 上拆分堆栈是不必要的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19450145/

相关文章:

go - 获取 bigInt 数 golang 的总和

go - 在 Golang 中复制 net.IP

linux - Nasm Linux x64-86 |在文件末尾添加位以进行正确的 base 64 编码

python - 如何使用shutil.make_archive创建zip64存档

C# 在其他线程上执行代码

c++ - 让一个 boost 线程休眠几纳秒

轮类次数太大

linux - 如何将字符串中的一个字符与 NASM x86_64 Linux 程序集中的另一个字符进行比较

java - 崩溃后停止线程/线程调用自身中断?

java - 为什么用户编写的run方法()启动一个新线程?