内存中的硬编码数据存储和位运算中的使用 (C)

Hardcoded data storage in memory and usage in bitwise operations (C)

我正在为 ARM 和 DSP 代码重新编写一个 C 项目(我对 ARM、DSP 和 C 比较陌生...谈论灾难...大声笑)并找到了开发人员实现的一段代码按位运算。我不确定,但在我看来,他们可能没有实现他们设定的目标。

他们为状态创建了一个 uint32,我认为其目的是只使用 32 位来表示 32 个 bool 值,但是他们随后创建了 32 个变量,每个变量都有位值他们试图创建的变量。这是一个简短的例子

// The status variable
uint32 STATUSES;
    
// The hard-coded values
const uint32 ACTIVE = 0x00000001;
const uint32 OPEN = 0x00000002;
const uint32 RUNNING = 0x00000003;
// etc.

然后他们通过执行以下操作

继续检查 STATUSES 变量的状态
if (STATUSES & ACTIVE)
{
    //  do something
}

我理解按位部分。如果该位在 STATUSES 中处于活动状态,则该值的计算结果将为真,因为仅当两个位都为真时,按位与才为真。

我的假设是使用按位运算的目的是减少程序的内存占用,但是他们创建常量变量来存储比较值的事实是否否定了按位运算的全部意义第一名?

通过创建状态变量,然后创建常量,他们使用的内存是否比仅使用 32 个布尔值要多? (bool = 1个字节,int = 2到4个字节,不知道这个系统是什么)

此外,如果他们想使用按位运算并真正保存 space,那么做下面这样的事情不是更好吗

// The status variable
uint32 STATUSES;
    
// Constants to compare against
uint32 ACTIVE() { return 0x00000001; }
uint32 OPEN() { return 0x00000002; }
uint32 RUNNING() { return 0x00000003; }
etc.

我知道在基于 OOP 的编程中内存分配如下:

该代码用于科学仪器,因此我们需要尽可能快地运行,同时使用尽可能少的内存。他们的方法是否比我建议的方法调用选项更快?哪个内存用来存放我写的硬编码比较方法?

如果能深入了解为什么他们会按照他们的方式完成实施,我们将不胜感激。

p.s。 None 参与创建该软件的人员已经不在了。

当您使用全局 const 值(在声明中初始化,具有内部链接)时,编译器会将值直接放入代码中,而不是引用其存储位置。

只要你不取那些变量的地址,根本就不会为它们分配存储空间。

which I assume the intent was to only use 32 bits for 32 bool values

不,它的意图似乎是创建各种位掩码。 RUNNING = 0x00000003 不能被视为布尔值,而是由 ACTIVE | OPEN.

组成的位掩码

值得注意的是,当 C 标准已经在 stdint.h 中定义了 uint32_t 时,创建您自己的本地(非)标准 uint32 类型毫无意义。发明自己的本地(非)标准只不过是一种不好的做法——你所获得的只是降低了可读性和可移植性。 (如果您的代码库 pre-dates 1999 年那么这也可以解释为什么没有使用标准类型。)

however doesn't the fact that they created constant variables to store the comparison values negate the whole point of doing bitwise in the first place?

在嵌入式系统中,数字常量要么与程序代码一起存储,要么存储在特殊的 .rodata 段中 - 无论哪种情况,它都会消耗闪存而不是 RAM。如果意图是从 RAM 执行,那么确实可能没有保存内存。此外,根据硬件的不同,从闪存中获取值可能比从 RAM 中获取值更昂贵。

您可能会发现 post 关于 C 变量最终在微控制器中的位置有用:What resides in the different memory types of a microcontroller? 我对 DSP 的经验也有限,但它们与微控制器的共同点通常比与 PC 的共同点多得多.您可能想要找到由链接器生成的“映射文件”,以详细查看分配的所有内容的最终位置。

此外,如果您的 DSP 在 32 位类型上工作得最好,那么在 32 位块中分配所有内容是内存优化的速度。

uint32 ACTIVE() { return 0x00000001; } 等都是废话,它只会被优化回 0x00000001 因为编译器会内联函数。

请注意,输入 0x00000001 等没有 u 后缀的十六进制文字是危险的做法。这确实 not 意味着它们是 32 位宽,而是它们的类型(有符号)int 到值 0x80000000 突然变成 unsigned int.