gpt4 book ai didi

c++ - 优化switch(x),x是作为参数传递的常量

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:14:54 25 4
gpt4 key购买 nike

我必须调用 f(0)f(1)
参数(01)仅在 switch-case(s) 中使用。
如何强制/引导编译器尽可能优化 switch-case(从下面的“昂贵”版本到“廉价”版本)?

来自 godbolt demo , switch-case 没有被优化掉。

示例:昂贵

int f(int n) {
switch(n) {
case 0: {
return 5;
};break;

case 1: {
return 10;
};break;
}

return 15;
}

int main(){
f(0);
}

示例:便宜(我的梦想)

int f0(){
return 5;
}

int f1(){
return 10;
}

int main(){
f0();
}

更多信息:-

在实际情况下,不仅仅是 0 和 1 - 它们是枚举类。
该参数在用户方面始终不变,例如f(CALLBACK_BEGIN), f(CALLBACK_END)

为什么我不能只使用 f0()/f1()?

我想把它组合成一个函数,因为有时我想创建一个传递函数。如果我可以像这样编码它会更容易维护:-

int g(int n){  .... }
int f(int n){ return g(n); }

它比 :- 更容易维护

int g0(){ .... }    int g1(){ .... }
int f0(){ return g0(); }
int f1(){ return g1(); }

我也更喜欢避免模板,所以我不能使用 Optimize Template replacement of a switch 中的解决方案.我的理由是:-

  • 模板必须在 header 中实现。
  • 我需要它在 .cpp 中,所以我必须将它间接指向另一个非模板函数。
    它很快就会变脏。

过早优化?

在我的例子中,每秒调用 60*10000+ 次。

编辑

我误解了 godbolt 演示的结果。它实际上是优化的。
(感谢 M.MBenoît 指出。)

编辑2

收到两个很好的答案后,我测试了一下,发现Visual C++非常聪明。
它可以优化如下:-

int f(int p1,int p2){
if(p1==0 && p2==1){ //zero cost

}
}
f(0,1); //inside main

实际情况下,有3-5层函数间接寻址,但Visual C++还是能找到!

结果与类似的帖子一致:Constant condition in a loop: compiler optimization

最佳答案

一个简单的解决方案是使您的函数 constexpr,这可以大大简化优化。

//  v--- that
constexpr int f(int n) {
switch(n) {
case 0: {
return 5;
};break;

case 1: {
return 10;
};break;
}

return 15;
}

这使得该函数在编译时可调用。如果传递的参数是 constexpr 值,则该函数可以在编译过程中由编译器执行。由于您将枚举值作为参数传递,因此该函数很可能在编译时执行。

如果您的繁重函数需要一些运行时值,请尝试分解出可以标记为 constexpr 的部分,并可能使用模板(它们确实有助于加快代码速度!)

constexpr int const_part_of_f(int n) {
switch(n) {
case 0: {
return 5;
};break;

case 1: {
return 10;
};break;
}
}

template<int n>
int f() {
if (get_runtime_value()) {
// Since `n` is a compile time constant, the result of `const_part_of_f` is
// evaluated at compile time, even if `f` is not a constexpr function.
return const_part_of_f(n)
}

return 15;
}

如果你真的想帮助优化器,避免过多的内存分配。例如,如果您需要一个在编译时已知的特定大小的数组,请使用 std::array 而不是 std::vector

正如其他用户所指出的,二进制膨胀是为了初始化 iostream 全局变量。然而,这并不否认 constexpr 函数更容易被编译器优化的事实。

关于c++ - 优化switch(x),x是作为参数传递的常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46046896/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com