简体   繁体   English

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

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

I am reworking a C project for ARM and DSP code (I'm relatively new to ARM, DSP and C... talk about a disaster... lol) and found a piece of code where the developers implemented bitwise operations.我正在为 ARM 和 DSP 代码重新设计一个 C 项目(我对 ARM、DSP 和 C 比较陌生……谈论一场灾难……哈哈)并找到了一段代码,开发人员在其中实现了按位运算。 I'm uncertain, but it seems to me that they might not have achieved what they set out to achieve.我不确定,但在我看来,他们可能没有达到他们设定的目标。

They created a uint32 for statuses, which I assume the intent was to only use 32 bits for 32 bool values, however they then went and created 32 variables, each with the bit value of the variables they are trying to create.他们为状态创建了一个uint32 ,我假设其意图是仅将 32 位用于 32 个bool值,但是他们随后创建了 32 个变量,每个变量都有他们试图创建的变量的位值。 Here is a shortened example这是一个简短的示例

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

They then proceed to check the status of the STATUSES variable by doing the following然后他们通过执行以下操作继续检查STATUSES变量的状态

if (STATUSES & ACTIVE)
{
    //  do something
}

I understand the bitwise part.我理解按位部分。 If the bit is active in STATUSES then the value would evaluate to true, because bitwise AND is true only when both bits are true.如果该位在STATUSES中处于活动状态,则该值将评估为真,因为仅当两个位都为真时,按位与才为真。

My assumption is that the purpose of using bitwise operations, is to reduce the memory footprint of the program, 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?我的假设是使用按位运算的目的是减少程序的内存占用,但是他们创建常量变量来存储比较值的事实是否首先否定了按位操作的全部意义?

By creating a status variable, and then creating constants, aren't they using more memory than if they simply used 32 bools?通过创建状态变量,然后创建常量,它们使用的内存不是比仅使用 32 个布尔值更多吗? ( bool = 1 byte, int = 2 to 4 bytes, not sure what it is in this system) bool = 1 字节, int = 2 到 4 字节,不确定在这个系统中是什么)

Also, if they wanted to use bitwise operations and truly save the space, would it not have been better to do something like the following另外,如果他们想使用按位运算并真正节省空间,那么执行以下操作会不会更好

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

I know in OOP-based programming memory is allocated as follows:我知道在基于 OOP 的编程中,内存分配如下:

  • local variable (primitives) -> stack局部变量(基元)-> 堆栈
  • new keyword (objects) -> heap新关键字(对象)-> 堆
  • hard coded -> ???硬编码 -> ??? not sure没有把握

The code is for a scientific instrument so we need to go as fast as possible while using as little memory as possible.该代码用于科学仪器,因此我们需要尽可能快地使用尽可能少的内存。 Is their method faster than the method-calling option I proposed?他们的方法比我提出的方法调用选项快吗? Which memory is used to store the hard-coded comparison method I wrote?我写的硬编码比较方法是用哪个内存存储的?

Any insights into why they might have done their implementation the way they did would be greatly appreciated.任何关于他们为什么会以他们的方式完成实施的见解将不胜感激。

ps None of the people who were involved in creating the software are around any more. ps 参与创建该软件的人都不在了。

When you use a global const value (initialized in the declaration, with internal linkage), the compiler will put the value directly into the code instead of referencing its storage location.当您使用全局const值(在声明中初始化,具有内部链接)时,编译器会将值直接放入代码中,而不是引用其存储位置。

As long as you don't take the address of those variables, no storage will be allocated for them at all.只要您不获取这些变量的地址,就根本不会为它们分配存储空间。

which I assume the intent was to only use 32 bits for 32 bool values我认为其意图是仅将 32 位用于 32 个布尔值

No, it rather looks like the intent was to create various bit masks.不,看起来其目的是创建各种位掩码。 RUNNING = 0x00000003 cannot be regarded as a bool but rather as a bit mask consisting of ACTIVE | OPEN RUNNING = 0x00000003不能被视为布尔值,而是由ACTIVE | OPEN组成的位掩码。 ACTIVE | OPEN . ACTIVE | OPEN

Notably, it's sensless to create your own local (non)standard uint32 type when the C standard already defines uint32_t in stdint.h .值得注意的是,当 C 标准已经在stdint.h中定义了uint32_t时,创建自己的本地(非)标准uint32类型是没有意义的。 Inventing your own local (non)standard is nothing but bad practice - all you achieve is reduced readability and portability.发明你自己的本地(非)标准只不过是不好的做法——你所获得的只是降低了可读性和可移植性。 (In case your code base pre-dates year 1999 then that would also explain why no standard types were used.) (如果您的代码库早于 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?但是,他们创建常量变量来存储比较值这一事实是否首先否定了按位执行的全部意义?

In embedded systems, numeric constants will either get stored together with the program code or in a special .rodata segment - in either case it consumes flash and not RAM.在嵌入式系统中,数字常量要么与程序代码一起存储,要么存储在一个特殊的.rodata段中——在任何一种情况下,它都会消耗闪存而不是 RAM。 If the intent is to execute from RAM then indeed there's likely no memory saved.如果意图是从 RAM 执行,那么确实可能没有保存内存。 Also, depending on hardware, grabbing values from flash might be more expensive than grabbing them from RAM.此外,根据硬件的不同,从闪存中获取值可能比从 RAM 中获取值更昂贵。

You might find this post regarding where C variables end up in microcontrollers useful: What resides in the different memory types of a microcontroller?您可能会发现这篇关于 C 变量最终在微控制器中的位置有用的帖子:什么存在于微控制器的不同内存类型中? I have limited experience of DSPs too, but they generally have much more in common with microcontrollers than with PC.我对 DSP 的经验也有限,但它们与微控制器的共同点通常比与 PC 的共同点要多得多。 You might want to locate your "map file", generated by the linker, to see in detail where everything allocated ended up.您可能希望找到由链接器生成的“映射文件”,以详细查看分配的所有内容的最终位置。

Also in case your DSP works best with 32 bit types, then allocating everything in 32 bit chunks is a speed over memory optimization.此外,如果您的 DSP 最适合 32 位类型,那么将所有内容分配到 32 位块中是一种内存优化速度。

uint32 ACTIVE() { return 0x00000001; } uint32 ACTIVE() { return 0x00000001; } etc is nonsense, it will just get optimized back to 0x00000001 as the compiler will inline the function. uint32 ACTIVE() { return 0x00000001; } etc 是胡说八道,它只会被优化回0x00000001 ,因为编译器将内联函数。

Please note that typing out hex literals like 0x00000001 without u suffix is dangerous practice.请注意,在没有u后缀的情况下输入0x00000001等十六进制文字是危险的做法。 This does not mean that they are 32 bit wide, but rather that they have type (signed) int up to value 0x80000000 which is suddenly type unsigned int .并不意味着它们是 32 位宽的,而是它们的类型(有符号) int的值最高为0x80000000 ,它突然变成了unsigned int类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM