我正在考虑函数式语言可以更直接地与其硬件相关联的方式,并且想知道垃圾收集的任何硬件实现。
这将显着加快速度,因为硬件本身将隐式处理所有收集,而不是某些环境的运行时。
这是 LISP Machines 所做的吗?有没有对这个想法进行进一步的研究?这是否太特定于域?
想法?反对?讨论。
我正在考虑函数式语言可以更直接地与其硬件相关联的方式,并且想知道垃圾收集的任何硬件实现。
这将显着加快速度,因为硬件本身将隐式处理所有收集,而不是某些环境的运行时。
这是 LISP Machines 所做的吗?有没有对这个想法进行进一步的研究?这是否太特定于域?
想法?反对?讨论。
由于分代收集,我不得不说跟踪和复制并不是GC 的巨大瓶颈。
有什么帮助的是硬件辅助的 READ 屏障,它在进行堆栈扫描和标记堆时消除了“停止世界”暂停的需要。
Azul Systems 已经做到了这一点: http : //www.azulsystems.com/products/compute_appliance.htm 他们在 JavaOne 上发表了关于他们的硬件修改如何实现完全无暂停 GC 的演示。
另一个改进是用于跟踪记忆集的硬件辅助写入屏障。
分代 GC,对于 G1 或 Garbage First,更是如此,通过仅扫描分区并保留跨分区指针的记忆集列表来减少它们必须扫描的堆数量。
问题是这意味着任何时候 mutator 设置一个指针,它也必须在适当的 rememered 集中放置一个条目。因此,即使您不进行 GC,您也有(小)开销。如果你能减少这个,你将减少 GC 所需的暂停时间和整体程序性能。
一个明显的解决方案是使用大于可用 RAM 的内存指针,例如,32 位机器上的 34 位指针。或者,当您只有 16MB 的 RAM (2^24) 时,使用 32 位机器的最高 8 位。苏黎世联邦理工学院的Oberon 机器使用这种方案取得了很大的成功,直到 RAM 变得太便宜。那是在 1994 年左右,所以这个想法已经很老了。
这为您提供了一些可以存储对象状态的位(例如“这是一个新对象”和“我刚刚触摸了这个对象”)。在进行 GC 时,更喜欢带有“这是新的”的对象并避免“刚刚接触”。
这实际上可能会看到复兴,因为没有人拥有 2^64 字节的 RAM(= 2^67 位;宇宙中大约有 10^80 ~ 2^240 个原子,因此可能永远不可能拥有那么多RAM)。这意味着如果虚拟机可以告诉操作系统如何映射内存,您可以在今天的机器中使用几个位。
是的。查看这2篇论文的相关工作部分:
https://research.microsoft.com/en-us/um/people/simonpj/papers/parallel-gc/index.htm http://www.filpizlo.com/papers/pizlo-ismm2007-stopless.pdf
或者在这个:
http://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon12StallFree.pdf
有一篇关于 lambda the Ultimate 的文章描述了如何需要一个支持 GC 的虚拟内存管理器来实现真正高效的 GC,而如今 VM 映射主要由硬件完成。这个给你 :)
你是一名研究生,听起来对我来说是一个研究资助的好话题。查看 FPGA 设计和计算机架构,在http://www.opencores.org/上有大量免费的处理器设计可用
垃圾收集可以作为后台任务实现,它已经用于并行操作。
皮特
我很确定应该存在一些原型。但是开发和生产硬件特定功能非常昂贵。在硬件层面实现 MMU 或 TLB 需要很长时间,这很容易实现。
GC 太大而无法有效地实现到硬件级别。
较旧的 sparc 系统具有可用于标记地址的标记内存(33 位)。今天没装?
这来自他们的 LISP 遗产 IIRC。
我的一个朋友构建了一个分代 GC,它通过从原语中窃取一点来标记。它工作得更好。
所以,是的,它可以做到,但是 nodody 不再需要标记东西了。
runT1mes 关于硬件辅助分代 GC 的评论值得一读。
给定一个足够大的门阵列(想到顶点 III),支持 GC 活动的增强型 MMU 将是可能的。
可能这里需要的最相关的数据是,目前在垃圾收集上花费了多少时间(占 CPU 时间的百分比)?这可能不是问题。
如果我们确实这样做了,我们必须考虑到硬件正在“在我们背后”欺骗内存。我想这将是“另一个线程”,用现代的话来说。如果正在检查某些内存可能不可用(也许可以通过双端口内存解决),当然如果 HWGC 要移动东西,那么它必须锁定其他进程,以免干扰它们. 并以适合所使用的架构和语言的方式进行。所以,是的,特定领域。
看看刚刚出现了什么……在另一篇文章中……查看 java 的 GC 日志。
我认为最大的问题是 CPU 寄存器和堆栈。在 GC 期间您必须做的一件事是遍历系统中的所有指针,这意味着知道这些指针是什么。如果这些指针之一当前位于 CPU 寄存器中,那么您也必须遍历它。同样,如果您在堆栈上有一个指针。因此,每个堆栈帧都必须有某种映射说明什么是指针,什么不是指针,并且在进行任何 GC 遍历之前,您必须将任何指针取出到内存中。
您还会遇到闭包和延续的问题,因为突然您的堆栈不再是一个简单的 LIFO 结构。
显而易见的方法是永远不要将指针保存在 CPU 堆栈或寄存器中。相反,您将每个堆栈帧作为指向其前身的对象。但这会扼杀性能。
上世纪 80 年代,麻省理工学院的几位伟人创造了SCHEME-79芯片,该芯片直接解释了 Scheme 的一种方言,采用 LISP DSL 设计,并内置了 hardware-gc。
为什么它会“加快速度”?硬件到底应该做什么?它仍然需要遍历对象之间的所有引用,这意味着它必须遍历主内存中的一大块数据,这也是它需要时间的主要原因。你会从中得到什么?您认为通过硬件支持可以更快地完成哪个特定操作?垃圾收集器中的大部分工作只是跟踪指针/引用,偶尔将活动对象从一个堆复制到另一个堆。这与 CPU 已经支持的指令有何不同?
话虽如此,您为什么认为我们需要更快的垃圾收集?现代 GC 已经可以非常快速和高效,以至于它基本上是一个已解决的问题。