更高效的RAM布尔数组? Arduino环境

时间:2011-04-10 13:51:52

标签: c arduino boolean boolean-operations

我在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位数据中。

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

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

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

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

2 个答案:

答案 0 :(得分:6)

是的,您可以轻松使用屏蔽来解决这个问题..

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

要设置一点,只需将其移动到或更改为值values | (1 << i)(如果未设置,则必须将AND与0一起)。

另一种解决方案可能是使用压缩结构:

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

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

答案 1 :(得分:3)

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

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

  1. 计算位所在的数组的偏移量
  2. 检索该元素
  3. 计算您感兴趣的位所在的字节的偏移量
  4. 多次移动字节以将位置于最不重要的位置
  5. 掩盖所有但最不重要的位置
  6. 测试零/非零
  7. 将它们存储在单个数组元素中会将其分解为:

    1. 检索包含您感兴趣的布尔值的元素
    2. 测试零/非零
    3. 选择其中一个取决于您的存储和性能需求如何相互平衡,您打算如何使用数据以及您愿意做出哪些权衡取舍。在您的情况下,直接访问的方法会使存储空间增加8倍,导致内存不足并导致故障,因此它不在桌面上。这会使一些额外处理成本增加。

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

      另外请记住,Arduino中使用的微控制器并不是特别复杂,并且没有大型寄存器,因此包装成更大的像unsigned intunsigned long这样的东西可能最终会产生良好的效果。