标题可能听起来像是重复但不是,请先完整阅读。
故事如下,我从头开始构建基于Z80的计算机,我的意思是,将Z80,外围设备,RAM和ROM焊接在一起。但是一旦完成,我将获得超过64K的RAM(我使用内存库获得的内存比Z80能够寻址的更多),我不知道如何管理。我的想法是在计算机上编写一个简单的lisp解释器,但我还想要动态数组或字符串,我显然需要像malloc这样的东西。
所以问题是,一旦你有一块连续的记忆,你如何分割它并管理它?
和
你能告诉我一些完成此操作的方法/算法吗?我想保持简单,但也不要懒惰并且做得对。
我怀疑这个问题不适合Stack Overflow,但我真的不知道在哪里问它。
答案 0 :(得分:4)
你至少需要一些所谓的“常见”和“#39;经典Z80术语中的空间。您无法立即切换所有内存,或者丢失了指令和堆栈。
例如,如果您有32K固定,32K存储(这是迄今为止最简单的连接),那么您将为您的数据分配一堆库。然后,您需要为每个银行提供标准分配器(第一个/最后一个匹配),并简单地遍历银行以找到一个具有空间的银行。换句话说,问题不在于存储的malloc'问题是普通malloc问题的循环问题,小型机器有大量的trival malloc实现。
对于免费/ realloc,您还需要记住银行编号。 Realloc稍微复杂一些,因为数据可能会移动银行。
数据的难题就是如果你想尝试将某些东西放在一起(例如,你可以比较两个字符串而无需复制或连续的银行转换)
我认为如果我正在构建一台lisp机器,我已经开始使用68000了,但是8)
像小68K的东西 https://retrobrewcomputers.org/doku.php?id=boards:sbc:tiny68k
答案 1 :(得分:3)
(这是Alan Cox answer的补充)
如果存在不同的数据类型(而Lisp确实有它们:)),将这种类型用作主要条件并始终将整个库分配给一个类型(或可能是一组相似的类型)可能是有用的,然后在银行中根据其类型分配项目。理性的是,一种类型的数据通常会比与其他孩子一起玩更频繁地与该类型的孩子互动。将它们布置得彼此靠近将有助于减少银行转换。对于字符串来说尤其如此。
尽管这可能会浪费空间,但确实会减少搜索量(取决于c的银行结构)。根据可用块的数量(和铲除的数据),它很快就会相等。
类似地,在分配它时 可能有用的是将所有新数据分配到该类型的最后一个分配块中,而不是在之前的任何孔中搜索。同样,出于速度考虑,在存储新数据时也要减少垃圾收集时间。
仅当最新添加的块被填满时,才可以重组该块-或如果该块对于该数据类型来说并没有什么意义。这带来了两个好处:首先,只需要重组用于该数据类型(组)的存储体,而不必重组整个数据存储器,从而节省了垃圾回收时间。其次,也许更重要的是,随着时间的推移,最少使用的日期将移到该类型的“早期”区块,而经常更改的日期移到最后。这再次将减少银行需求,因为现在已经证明发生了很大变化(因此访问大量数据)的数据彼此靠近,甚至可能位于一个块内。
底线是试图将面向块(存储)的内存的劣势变成优势。