如何在不查看编译代码的情况下检查代码块是否已优化?

问题描述 投票:0回答:1

如何在不查看编译代码的情况下检查代码块是否已优化?

例如:

void Func(const int val) {
    const int minVal = 100;
    if(val > minVal) {
        // Complex code block
    }
}
...
Func(200);
for(int i = 0; i < 1000; ++i)
    Func(50);

如何检查

Func(50)
以及整个
for
循环是否已优化?
在这种情况下,编译器应该具备做出这样的决定的所有要素。

c++ compiler-optimization
1个回答
0
投票

这个问题不能一概而论地回答。这将取决于多种因素。不同编译器的结果有所不同,代码是否会被优化将取决于优化级别。

未优化的构建(即 O0)很可能会保留检查,因为它们通常甚至不会内联任何内容以使调试更容易(因此,它永远不知道“val”有什么值。

优化的构建可以优化这种情况,但有一个问题:编译器实际上需要能够看到翻译单元中的函数定义(而不是声明)。如果您在标头中声明“func”,在 cpp 文件中定义其实现,并在另一个 cpp 文件中使用“func”,则它将无法对其进行优化,除非某种链接时代码生成是用过的。 此外,编译器评估必须确定“func”实际上是值得内联的东西。这对于小函数来说是可能的,但对于较大的函数来说,这种可能性就较小。有编译器内联某些函数的提示和说明,但这些几乎不应该使用。

但是由于我们使用的是 C++,所以让我们再回答一个问题:如果您实际上需要确保该块被优化掉,甚至在调试构建中,该怎么办?好吧,我们可以做到这一点,尽管它有缺点:

template<int Val>
void Func() {
    static constexpr int minVal = 100;
    if constexpr(Val > minVal) {
        // Complex code block
    }
}

func<200>();

使用非类型模板参数,您实际上可以为函数指定一个编译时常量参数。将“minVal”更改为实际的 constexpr 常量,我们可以使用“if constexpr”强制编译器在编译时执行此检查(至少如果您可以访问 c++17)。 现在我并不是说你应该这样做——它有明显的缺点。现在“Val”实际上必须是一个常量参数,这一次。此外,对于每个编译单元中传入的每个“Val”,它将强制同一函数的多个实例化。它会对编译时间产生负面影响。但如果您的用例出于某种原因需要它,那么它是一个选项。尽管在实践中,如果 constexpr 是您主要在元编程上下文中使用的东西,而您已经在模板函数中。

© www.soinside.com 2019 - 2024. All rights reserved.