嵌入式编程中宏值之间的比较是否有害?

时间:2014-12-11 14:47:24

标签: c++ c performance macros embedded

我正在构建一个需要在ARM上运行的程序。 处理器有足够的资源来运行程序,所以这个问题与这种类型的处理器没有直接关系,而是与非强大的处理器有关,资源和计算能力都受到限制。

打印调试信息(甚至激活部分代码)我使用的是头文件,我在其中定义了我设置为true或false的宏,如下所示:

#define DEBUG_ADCS_OBC true

并在主程序中:

if (DEBUG_ADCS_OBC == true) {
    printf("O2A ");
    for (j = 0; j < 50; j++) {
        printf("%x ", buffer_obc[jj]);
    }
}

这是一个坏习惯吗?有更好的方法吗?

此外,这些IF检查是否会以可衡量的方式影响绩效?

或者可以安全地假设在编译代码时,IF会以某种方式从流中移除,因为在两个不能更改的值之间进行比较?

5 个答案:

答案 0 :(得分:7)

由于表达式DEBUG_ADCS_OBC == true可以在编译时进行评估,优化编译器会发现分支总是被占用或者总是被绕过,并且完全消除了这个条件。因此,当您使用优化的编译器时,表达式的运行时成本为零。

如果您在关闭所有优化的情况下进行编译,请改用条件编译。这将使优化编译器对常量表达式执行相同的操作,但是在预处理器阶段。因此,编译器不会看到&#34;即使关闭了优化也是有条件的。

注1:由于DEBUG_ADCS_OBC具有布尔变量的含义,因此请使用DEBUG_ADCS_OBC而不是== true,以获得更清晰的外观。

注意2:不要在程序正文中定义值,而应考虑在命令行上传递值,例如-DDEBUG_ADCS_OBC=true。这使您无需修改​​源代码即可更改调试设置,只需操作make文件或其中一个选项即可。

答案 1 :(得分:4)

每次程序到达此行时,都会评估您使用的代码。由于DEBUG_ADCS_OBC的每次更改都需要重新编译代码,因此您应该使用#ifdef / #ifndef表达式。它们的优点是,它们仅在编译时进行一次评估。

您的代码段可能如下所示:

部首:

//Remove this line if debugging should be disabled
#define DEBUG_DCS_OBS

来源:

#ifdef DEBUG_DCS_OBS

printf("O2A ");
for (j = 0; j < 50; j++) {
    printf("%x ", buffer_obc[jj]);
}

#endif

答案 2 :(得分:3)

让编译器执行此操作的问题是对常量表达式进行不必要的运行时测试。优化编译器将删除它,但同样可能会发出有关常量表达式的警告,或者当宏未定义时,会发出有关无法访问代码的警告。

在嵌入式编程中,这不是一个问题&#34;它在任何编程领域都没有什么优点。

以下是更多常用的习惯用法,不会在最终版本中包含无法访问的代码,并且在适当配置的语法中,突出显示编辑器或IDE通常会显示哪些代码段处于活动状态,哪些是不

#define DEBUG_ADCS_OBC

...

#if defined DEBUG_ADCS_OBC
    printf("O2A ");
    for (j = 0; j < 50; j++) 
    {
        printf("%x ", buffer_obc[jj]);
    }
#endif

答案 3 :(得分:2)

我会添加一件没有被提及的东西。

如果在调试版本上禁用了优化,即使运行时性能影响微不足道,代码仍会包含在内。因此,调试版本通常比发布版本更大。

如果你的内存非常有限,你可能会遇到版本构建适合设备内存并且调试版本不适合的情况。

出于这个原因,我更喜欢编译时#if而不是运行时if。我可以保持调试版本和发布版本之间的内存使用更加接近,并且在项目结束时更容易继续使用调试器。

答案 4 :(得分:2)

优化器将解决其他回复中提到的额外资源问题,但我想补充另一点。从代码可读性的角度来看,这段代码会重复很多次,因此您可以考虑创建特定的打印宏。这些宏是调试启用或禁用宏所应包含的内容。

#ifdef DEBUG_DCS_OBS
myCustomPrint    //your custom printing code
#else
myCustomPrint    //No code here
#end

此外,这将降低在任何文件中遗忘宏的可能性,这将导致真正的优化问题。