首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >amd64上的分叉栈

amd64上的分叉栈
EN

Stack Overflow用户
提问于 2013-10-18 12:50:52
回答 3查看 1.3K关注 0票数 15

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

典型多线程程序的内存使用量可以显著减少,因为每个线程不需要最坏的堆栈大小。可以在32位地址空间中运行数百万个线程(无论是完整的NPTL线程还是共同例程)。-- 伊恩·兰斯·泰勒

...implying,一个64位的地址空间已经可以处理它.

还有..。

..。分裂堆栈和狭窄用例的持续开销(在32位架构上产生大量的I/O绑定任务)是不可接受的.-- 布斯林

两个问题:他们是这么说的吗?第二,如果是这样的话,为什么他们在64位架构上不相关呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-10-18 14:11:39

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

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

在目前使用的平面记忆模型中,虚拟地址到语音存储位置的转换是在硬件MMU的支持下完成的。在amd64上,将64位虚拟地址空间的大块保留到正在创建的每个新堆栈上更好(这意味着总体速度更快),而只将第一页(4kB)映射到实际内存。这样,栈将能够根据需要增长和缩小,超过连续的虚拟地址(意味着每个功能序言中的代码较少,这是一个很大的优化),而操作系统则重新配置MMU,将每一页虚拟地址映射到一个实际的空闲内存页面,每当堆栈在某些可配置阈值之上或以下扩展或缩小。

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

PS:目前的Go实现远远落后于这其中的任何一个:-)

票数 19
EN

Stack Overflow用户

发布于 2013-10-18 13:43:01

Go的核心团队目前是讨论,在未来的围棋版本中使用连续堆栈的可能性。

拆分堆栈方法很有用,因为堆栈可以更灵活地增长,但它也需要运行时分配相对较大的内存块来跨层分布这些堆栈。关于Go的内存使用有很多混乱,部分原因就是这个。

使连续但可增长(可重定位)堆栈是一个选项,它将提供同样的灵活性,并可能减少对Go的内存使用的混淆。以及在低内存机器(见链接线程)上纠正一些不好的角落情况。

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

票数 9
EN

Stack Overflow用户

发布于 2014-03-27 10:21:24

更新Go 1.4 (Q4,2014年)

更改为运行时

到1.4,运行时(垃圾收集器、并发支持、接口管理、映射、切片、字符串、.)大部分是用C编写的,有一些汇编程序支持。 在1.4中,已经翻译了很多代码,以便垃圾收集器能够在运行时扫描程序堆栈,并获得有关哪些变量是活动的的准确信息。 这种重写允许1.4中的垃圾收集器完全准确,这意味着它知道程序中所有活动指针的位置。这意味着堆将更小,因为不会出现假阳性,从而保持非指针活动。其他相关的更改也会减少堆的大小,与以前的版本相比,堆的大小总体上要小10%-30%。 其结果是堆栈不再被分割,从而消除了“热分割”问题。当达到堆栈限制时,将分配一个新的、更大的堆栈,在那里复制goroutine的所有活动帧,并更新堆栈中的任何指针。

初步答复(2014年3月)

Anastasopoulo的文章"围棋中的连续堆栈“也谈到了这个问题。

在这样的情况下,堆栈边界恰好落在一个紧密的循环中,重复创建和销毁段的开销就变得很大。 这被称为围棋社区内部的“热分割”问题。 “热分割”将在Go 1.3中通过实现连续堆栈来解决。 现在,当堆栈需要增长,而不是分配一个新段时,会发生以下情况:

  1. 创建一个新的、更大的堆栈
  2. 将旧堆栈的内容复制到新堆栈中。
  3. 重新调整每个复制的指针以指向新地址。
  4. 摧毁旧的堆栈

下面提到一个主要出现在32位结构中的问题:

不过,也有一定的挑战。 1.2运行时不知道堆栈中指针大小的单词是否是实际的指针,或者不是。可能会有浮点数,而最少见的整数,如果被解释为指针,实际上会指向数据。 由于缺乏这样的知识,垃圾收集器必须保守地考虑堆栈帧中的所有位置为根。这就留下了内存泄漏的可能性,特别是在32位架构上,因为它们的地址池要小得多。 然而,在复制堆栈时,必须避免这种情况,并且在重新调整时只应考虑真正的指针。 虽然已经完成了工作有关活动堆栈指针的信息现在嵌入到二进制文件中,并可用于运行时。 这不仅意味着1.3中的收集器可以http://talks.golang.org/2014/go1.3.slide#4堆栈数据,而且现在可以重新调整堆栈指针。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19450145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档