5

我在 Arduino 环境中有一些代码需要 x(以 8 为增量)布尔值,这些值在运行时可对某些移位寄存器代码进行操作。所以目前我正在使用这样的布尔数组:

 #define number_of_shiftRegisters 220 //num of 8 bit shift registers

 #define numOfRegisterPins number_of_shiftRegisters * 8 //number of booleans needed

 boolean registers[numOfRegisterPins]; //boolean array

但是我的 RAM 大约 200(1600 个布尔值)用完了,直到我看到这一点才知道为什么,即使布尔值是 1 位,它们也存储在 8 位数据中。

正如我之前所说,所需的布尔数总是以 8 为增量,所以我不知道这是否对我有利。

是否有更高效的内存方式来存储 1000 多个布尔值并且仍然能够通过索引引用它们?

或者......至少更高效的内存不会花费更多的CPU时间来设置和迭代?

我曾考虑过一个char数组,然后对每个字符进行位掩码以访问各个位。但我不知道是否有更简单的方法,或者这是否会占用更多的 CPU 时间。

4

2 回答 2

6

是的,您可以轻松地使用遮罩来解决该问题。

每个字节(无符号字符)将包含 8 个布尔值,以获得第 i 个您可以values & (1 << i)在 if 测试中使用的值,它会起作用,因为如果设置了正确的位,那么结果将是 != 为 0。

要设置一点,只需将其和或移至值:( values | (1 << i)如果未设置,您必须将其与 0 相加)。

另一种解决方案可能是使用打包结构:

struct Bools
{
  int b1 : 1;
  int b2 : 1;
  int b3 : 1;
  ... // up to b8
}

这应该管理可以直接访问布尔值的元素,并允许您定义一个联合来将它们管理为 8 个单比特布尔值或字节。

于 2011-04-10T13:57:08.887 回答
3

您可以具有内存效率或计算效率,但您不能同时拥有两者。

将布尔值打包成一个数组unsigned char意味着对于任何随机读取访问,您必须:

  1. 计算位所在数组的偏移量
  2. 检索该元素
  3. 计算您感兴趣的位所在字节的偏移量
  4. 多次移动字节以将位定位在最不重要的位置
  5. 屏蔽除最不重要的位置以外的所有位置
  6. 测试零/非零

将它们存储在单独的数组元素中会将其缩减为:

  1. 检索包含您感兴趣的布尔值的元素
  2. 测试零/非零

选择其中一个取决于您的存储和性能需求如何相互平衡、您打算如何使用数据以及您愿意做出哪些权衡。在您的情况下,直接访问方法的存储成本增加了八倍,这会使您的内存不足并导致故障,因此无法解决。这以一些额外的处理为代价留下了打包的位。

如果您花费大量时间迭代全部或部分集合,则可以使用打包方法并通过仅在需要时检索字节并在每次执行时进行一次移位和掩码来减少一些计算下一点。 立即执行此操作将是过早的优化,因此只需将其放在您的后袋中,直到您发现访问实际上导致了瓶颈。让您的程序首先运行可用内存。

还要记住,Arduino 中使用的微控制器并不是特别复杂,也没有大寄存器,所以打包成更大的东西,unsigned int或者unsigned long最终可能会产生反作用。

于 2011-04-10T15:05:53.543 回答