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

bro*_*s94 15 64-bit multithreading callstack go rust

似乎有一种观点认为在64位体系结构上使用"拆分堆栈"运行时模型是不必要的.我说似乎是,因为我还没有看到有人说过,只能围着它跳舞:

典型的多线程程序的内存使用量可能会显着降低,因为每个线程不需要最坏情况的堆栈大小.可以在32位地址空间中运行数百万个线程(完整的NPTL线程或协同例程).- 伊恩兰斯泰勒

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

和...

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

两个问题:这是他们说的吗?其次,如果是这样,为什么它们在64位架构上不必要?

Tob*_*bia 19

是的,这就是他们所说的.

在64位体系结构上(当前)不需要拆分堆栈,因为64位虚拟地址空间非常大,可以包含数百万个堆栈地址范围,如果需要,每个堆栈地址范围都大到整个32位地址空间.

在当今使用的Flat存储器模型中,在硬件MMU的支持下完成从虚拟地址到物理存储器位置的转换.在amd64上,事实证明,将64位虚拟地址空间的大块保留给正在创建的每个新堆栈更好(意味着整体更快),同时只将第一页(4kB)映射到实际RAM.这样,堆栈将能够根据需要在连续的虚拟地址(意味着每个函数序言中的代码更少,一个大的优化)上增长和缩小,同时操作系统重新配置MMU以将每个虚拟地址页面映射到实际每当堆栈增长或收缩高于/低于某些可配置阈值时,RAM的空闲页面.

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

PS:目前的Go实施远远落后于此:-)

  • 它没有定义,它只是语言或编译器的选择.我应该更清楚,我会编辑它. (2认同)

thw*_*hwd 9

Go核心团队目前正在讨论在未来的Go版本中使用连续堆栈的可能性.

拆分堆栈方法很有用,因为堆栈可以更灵活地增长,但它还要求运行时分配相对较大的内存块来分配这些堆栈.关于Go的内存使用存在很多混淆,部分原因在于此.

制作连续但可增长(可重定位)的堆栈是一种可以提供相同灵活性并可能减少对Go内存使用的混淆的选项.以及补救低内存机器上的一些不良角落(参见链接线程).

至于32位与64位架构的优缺点,我认为没有任何直接关联使用分段堆栈.