当前位置: 首页 > 面试题库 >

在AMD64上不必要地拆分堆栈

钱睿范
2023-03-14
问题内容

似乎有人认为,在64位体系结构上不需要使用“拆分堆栈”运行时模型。我说的似乎是,因为我还没有看到任何人真的这么说,只在它周围跳舞:

由于每个线程不需要最坏情况的堆栈大小,因此典型的多线程程序的内存使用量可能会大大减少。在32位地址空间中运行数百万个线程(完整的NPTL线程或协程序)成为可能。-
伊恩·兰斯·泰勒(Ian Lance
Taylor)

…暗示一个64位地址空间已经可以处理它。

和…

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

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


问题答案:

是的,这就是他们的意思。

(当前)在64位体系结构上不需要拆分堆栈,因为64位虚拟地址空间是如此之大,它可以包含数百万个堆栈地址范围,如果需要,每个地址范围都可以与整个32位地址空间一样大。

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

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

PS:当前的Go实施远不及以下任何一项:-)



 类似资料:
  • 问题内容: 在我拥有的一个小程序(尤其是cgo调用)上,go build和go run非常慢。我想缓存二进制文件,以便仅在源文件较新时才重建。我会使用带有%规则的简单Makefile,但是语言设计人员声称go的构建支持不需要Makefile。 我还有其他选择吗?go社区是否愿意使用另一个构建系统(可能是基于哈希的构建系统)来缓存和重用构建产品? 问题答案: 我写了一个工具来解决这个问题。单独不会检

  • 问题内容: 我有一个BaseActivity,其他所有活动都可以对其进行扩展。关键是,每当用户离开活动时,我都会将音乐静音。我也停止听电话。 问题是,只要用户在活动之间进行切换,就会被调用,这意味着该应用程序不必要地静音和停止,即使仅当用户离开该应用程序时该静音也应该停止。 现在说我在和之间切换。即使我只想 在用户离开应用程序时* 被调用,此开关也 不必要 执行。我该怎么办? * 感谢您的专家意见

  • 我正在使用Spring Data JPA,以违反直觉的行为运行以下测试结果 进一步研究Hibernate的代码库,它出现在一个新线程上,persistentContext被清除干净。因此,就而言,我的实体变成了分离状态...创建了一系列决策,这些决策莫名其妙地导致生成一个新ID 我引用的特定代码位于:https://github.com/hibernate/hibernate-orm/blob/m

  • 我在不同的地方读到过这样做是出于“性能原因”,但我仍然想知道这种16字节对齐方式在哪些特定情况下提高了性能。或者,无论如何,选择它的原因是什么。 编辑:我认为我写这个问题的方式有误导性。我不是在问为什么处理器使用16字节对齐的内存会更快,这在文档中随处都有解释。相反,我想知道的是,强制的16字节对齐如何优于在需要时让程序员自己对齐堆栈。我这样问是因为根据我在汇编方面的经验,堆栈强制有两个问题:它只

  • 我有一个字符串。我需要找到外部标点符号并将它们从附加的单词中拆分出来,并将它们视为另一个单词。输出将是: 将是一个单词(内部标点符号) 小狗 将是两个单词, 我的代码根据外部标点符号拆分单词,但我希望它们作为单独的单词。 我该怎么做?

  • 我已经开发了一个app它的apk大小太大了(在启用progaurd,缩小图像大小,运行lint之后),我正在考虑使用split apk。我已经使用abi split我应该上传哪些apk,这样我可以覆盖最大的设备?我只想上传两个,可能吗??