Embedded 什么';这是康威'的高效实现;低内存使用的生活游戏?

Embedded 什么';这是康威'的高效实现;低内存使用的生活游戏?,embedded,conways-game-of-life,low-memory,Embedded,Conways Game Of Life,Low Memory,我正在寻找一种快速有效的方法来实现康威的生活游戏 限制条件:一块96x128板、大约2kB的可用RAM和52MHz处理器(请参阅此处的技术规格:) 我目前的简单解决方案是将每个单元格表示为矩阵中的一个位(96*128/8=1536字节),但工作起来太慢了。可以使用哪些技巧来提高性能 存储活细胞的坐标(例如在这个实现中)会占用太多内存。看起来像一个有趣的硬件。 在96x128像素的显示器上,每像素存储1位,可获得12288位。 你说的16384位中有一半以上是“可用的”。 如果你甚至不能在每个单元

我正在寻找一种快速有效的方法来实现康威的生活游戏

限制条件:一块96x128板、大约2kB的可用RAM和52MHz处理器(请参阅此处的技术规格:)

我目前的简单解决方案是将每个单元格表示为矩阵中的一个位(96*128/8=1536字节),但工作起来太慢了。可以使用哪些技巧来提高性能


存储活细胞的坐标(例如在这个实现中)会占用太多内存。

看起来像一个有趣的硬件。 在96x128像素的显示器上,每像素存储1位,可获得12288位。 你说的16384位中有一半以上是“可用的”。 如果你甚至不能在每个单元中存储2位,那么就没有足够的空间去做很多事情

一些想法:

  • 您有一个32位处理器。在这样一个处理器上,有几种比特旋转技巧来获取位图并计算几个并行单元的邻居数

  • 存储邻居计数通常更快,出生时增加所有8个邻居,死亡时减少所有8个邻居,而不是每一代从头开始重新计算邻居的数量——但看起来您没有足够的内存来使用这种方法

  • 也许您可以使用2x2像素/单元(因此只有3072个单元可见)或3x3像素/单元(因此只有1376个单元可见),这样您的软件工作更少,从而产生运行更快的错觉。(这也释放了足够的RAM,您可以进行上面提到的邻居计数)

  • 由于许多生命模式都有大面积的死区,因此可能会有一个“活动区域”的小位图——例如,一个12x16位数组,如果对应的8x8单元区域完全死区,则每个位都是“0”,如果对应区域中的任何单元都是活动的,则每个位都是“1”。下一代更新只需要查看活动区域和1个单元宽的死亡区域边界;您可以跳过检查死区的6x6单元核心。此外,如果8x8单元区域的4个最近相邻区域也死掉,则可以完全跳过整个8x8单元区域

  • 由于许多生命模式都有大面积的静态不变“静物”模式,因此可能有一个小的“动态区域”位图——例如,一个12x16位数组,如果对应的8x8单元区域在上一代更新中没有变化,则每个位都是“0”,以及“1”如果在上次更新中相应区域中的任何单元格发生了更改。下一代更新只需要查看动态区域和静态区域的1个单元范围的边界;您可以跳过检查静态区域的6x6单元核心,因为它在下一代中是相同的

  • 如果模式“足够大”,基于Gosper的Hashlife的表示可能比直接存储位图存储在更少的RAM中。唉,我怀疑你远远低于“足够大”的门槛


如果您有许可证可以滥用设备上剩余的30KB(也称为闪存),您可以随时将其存储在那里,这并不理想,但这是一种可能解决有限RAM问题的方法

从效率上讲,您将以CPU和内存性能相互交换:

为了提高内存效率,位数组可能是最佳的解决方案,但在网格中迭代会降低CPU效率


根据内存地址的容量和大小,您可以使用一个单元链表来避免在整个网格中迭代:这肯定会节省您扫描大量死区的时间。

对于小生命宇宙来说,让它们在所有面上缠绕(形成一个环形宇宙)是很常见的但这需要双重缓冲。在您的情况下,这需要3KB的RAM,但您只有2KB

如果你不包装,那么你就不需要加倍缓冲整个宇宙。在将单元格用作计算输入之前,只需避免覆盖单元格

假设你的宇宙是按传统位图布局的。我们将把它视为一系列在内存中按顺序排列的行。假设宇宙有四行,编号为0到3

  0
  1
  2
  3
  4
  ...
计算下一代时,将使用第2、3和4行(为空)计算第3行的新版本。您可以在第4行的顶部编写第3行的新版本。类似地,从第1、2、3行计算新行2,并将其写入第3行的顶部,因为在计算第2行后不再需要该数据。新行1根据行0、1、2计算并写入行2

这意味着您只需要额外一行的内存。97*128位为1552字节


缺点是你的宇宙在内存中滚动,你必须有一些机制来处理这个问题。在每次计算后将其复制回原始位置(速度较慢),或者安排从内存中的任何位置显示,并确保您的计算和显示系统可以从高地址到低地址进行转换。

查看迈克尔·艾布拉什的《生命游戏》一章。有一个实现将3个单元的当前和以前的状态编码为一个字,并使用查找表和进位生成下一个状态的技巧。速度惊人。

坚持使用位数组,并使用以下技巧跳过邻居计数:创建一个查找表,其中包含创建或维护活动单元格的相邻单元格块的可能位模式

如果您想最小化内存,可以将“索引”模式压缩为8位:上面一行的3位、列两边的2位和下面一行的3位。您可以在查找表中将输出编码为单个位,总共只占用256位。使用索引作为查找数组的位移位计数来“计算”结果。位移位和ari