在实现大多数算法(排序、搜索、图遍历等)时,通常会以牺牲额外的普通操作为代价来减少内存访问。
Knuth有一个比较各种算法实现复杂性的有用方法,它从特定的处理器中抽象出来,只区分普通操作(oops)和内存操作(mems)。
在编译程序中,通常让编译器组织低级操作,并希望操作系统处理数据是保存在缓存(更快)还是虚拟内存(更慢)的问题。此外,指令的确切数量和成本由编译器封装。
对于Forth,不再有这样的封装,它更接近于机器,尽管可能更接近于运行在寄存器处理器之上的堆栈机器。
忽略操作系统的影响(因此没有内存停滞等),并假设目前有一个简单的处理器,
(1)有谁能告诉我Forth中普通的堆栈操作(例如dup, rot, over, swap等)与Forth的内存访问fetch(@)或store(!)的成本如何比较吗?
(2)是否有一个经验法则,我可以用来决定有多少普通操作来权衡节省内存访问?
我要找的是像"内存访问的成本是50个普通操作,或500个普通操作,或5个普通操作"之类的东西。
我想了解一下fetch和store相对于rot, swap, dup, drop, over的相对开销,精确到一个数量级
这篇文章从内存中取出一个单词需要多少时间?讨论主内存的延迟时间,使用一些经验法则类型的数字,但基本上您可以在主内存延迟时执行许多指令。正如其他人所说,系统之间的数字差异很大。
主内存延迟是一个很大的兴趣领域,特别是cpu有更多的内核,但通常没有更快的内存带宽。关于压缩主存中的数据也有一些研究,以便CPU可以利用'备用'周期和紧密打包的缓存线http://oai.cwi.nl/oai/asset/15564/15564B.pdf
对于那些真正对细节感兴趣的人来说,大多数CPU制造商都发布了关于内存优化等的深度指南,主要针对高端和编译器编写者,但所有2gl和3gl程序员都可以阅读。
p。出去。
对于汇编程序和c编译器的输出(实际上是汇编程序)来说,比较内存取出和寄存器操作是可以的。在Forth,这个问题几乎没有意义。首先,Forth是一个解释器,在使用Forth时,人们放弃了速度的极限。当然,可以在Forth之上添加一个优化器,但这样问题就更没有意义了,因为c优化器和Forth优化器的输出收敛到——你猜对了——一个最优解。
让我们看一下Forth中的基本操作,比如AND。这是通过
实现的> CODE AND
> POP AX
> POP BX
> AND AX, BX
> PUSH AX
> NEXT
所以我们已经看到了三个内存操作,看起来像是一个基本的计算操作。看来Knuth度量并不适用。此外,福斯似乎输得很惨。然而,事实并非如此。这些内存操作都在典型处理器的L1缓存上。这和c小函数中的局部变量一样有效,我们可以使用变量和堆栈来比较堆栈操作和内存操作。答案很简单。变量有导致内存停滞的风险。堆栈操作几乎肯定是L1缓存命中。这是最重要的一点。不过问题明确要求不要考虑!所以。