纯粹为功能编程设计的CPU有何不同?


14

在一定程度上,CPU在设计时会考虑人们会为它隐式或显式编写的软件。

在我看来,如果您看一下指令集体系结构的设计,就每个指令编码一个命令式样式命令的意义而言,它们是非常“必要的”。在我看来,当前的指令集架构在某种程度上是基于程序员产生的代码类型而发展的。

如果一个人从头开始设计CPU,并且知道它只会运行以功能编程风格编写的程序,那么该CPU的设计将与现有CPU有何不同?


9
约翰·巴克斯(John Backus)在他的“编程可以从冯·诺伊曼风格中解放出来吗?”中 很少提及此类作品(第15节)。
Dmitri Urbanowicz

寻找(图形)归约机器,或访问您当地的研究图书馆,以期找到W. Kluge绝版书籍《归约,数据流和控制流系统的组织》(麻省理工学院出版社,1992年)。
Kai

2
另外,考普曼(Koopman)的书《组合图约简的体系结构》(AP,1990年)。研究Lisp机器可能也值得。en.wikipedia.org/wiki/Lisp_machine
别名

我认为从根本上说,随着时间的流逝,机器的状态将永远变得至关重要。
orlp

几个有用的CPU功能将是对重击和更有效跳转的本地支持。同样,CPU可能能够采取一些捷径,因为它知道在特定范围内不会覆盖内存中的某些位置,并且CPU不需要以与基于堆栈的语言相同的方式维护堆栈。
恢复莫妮卡

Answers:


3

实际上,它已经完成了:https : //en.wikipedia.org/wiki/Lisp_machine

FP的CPU设计的一方面是垃圾收集。GC对于函数式语言非常重要。常见的实现要求GC可以区分指针数据和非指针数据。有效地,这意味着在数据中存储额外的数据。因此,例如,OCaml整数在32位体系结构上仅为31位,在64位体系结构上仅为63位。整数算术然后涉及笨拙的额外移位操作。其他语言(或其他OCaml数据类型)可能浪费整个机器字来增加该位,因此将128位用于64位整数。本机设计用于GC的CPU可能具有65位数据总线,但具有64位算术。

也就是说,许多非功能性语言也具有垃圾回收功能,因此将从相应的体系结构中受益。

想到的另一件事是,FP的内存使用情况通常比命令性程序的使用情况分散得多。主要是因为使用数组不太自然。结果,这些程序从缓存连续的内存块中获利较少。因此,FP CPU可能使用不同的缓存策略。


1

它要么什么都不会改变,要么会像Reduceron及其后继产品PilGRIM 1那样利用庞大的堆栈使用大规模并行设置。

声明什么都不会改变的说法乍一看似乎是大胆的,但是由于CPU是顺序的,因此存在一个翻译过程(编译),该过程使用可用的硬件对其进行扩展以提高效率。应该有另一种体系结构,某些操作会更快,有些则需要黑客技巧来加快它的速度。

可能会有所作为的体系结构将需要地图操作和列表运行得更快(不是整个故事,但足以证明其效果)。无法创建动态更改的硬件来本地运行列表,因此这些列表将存储在连续的内存中。我们坚持某种形式的数组表示。对于map,要在非顺序设置中运行-我们回到Reduceron。这样有效地集中处理一个连续指令,并支持并行处理。

可能有所不同的是,可以加载多个功能并在不打乱框架的情况下运行它们-但是为功能添加多个单元会导致访问内存混乱。

添加到kne的答案中,GC作为协处理器运行将是有益的,这将是非常简洁的功能。

1:Boilijink A.,HölzenspiesPKF,Kuper J.(2011)介绍PilGRIM:一种用于执行惰性功能语言的处理器,对 PilGRIM进行了适当的描述在:Hage J.,MorazánMT(eds)中,功能语言的实现和应用。IFL2010。计算机科学讲义,第6647卷。施普林格,柏林,海德堡


“不可能使递归变为本地”。你能解释为什么吗?起初我感到很惊讶。
user56834 '19

此外,reduceron是否可能不是cppga上的硬核CPU?
user56834 '19

不好,我的意思是本机递归,但这与probalby无关。我必须修改一下。
Evil

0

首先开个玩笑:由于运行100%功能的程序永远无法做任何有用的事情,仅拥有一条NOP指令就足够了。(我将其用于火焰战争)。

因此,将需要一些用于IO的命令式指令以及对命令式编程的通常支持。

否则,部分取决于所使用的实际语言。我最想念的两个是Haskell和Erlang。

我相信Haskell可以从对列表和地图的支持中受益。特定的硬件内存映射可以支持列表,从而将链接的列表转换为连续的地址集。第一个元素可能在地址n上,第二个元素在地址n + 1上,依此类推。要从列表中删除第一个元素,只需更改指针n。最后,当您删除n指针时,可以释放所有内存。可以将地图作为关联数组支持-输入搜索值,然后内存系统返回该项目。无需迭代搜索。

反过来,Erlang可以受益于消息/进程的支持以及具有完整状态的尾部递归。消息和进程可以通过各种方式来支持,一个示例可能是拥有大量的处理核心。尾部递归可以通过内存控制器来改善,因为它知道可以更快地复制状态,也许不复制大量数据,而是简单地修改内存系统指针。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.