gpt4 book ai didi

c++ - 我可以鼓励 g++ 内联一个返回符号的开关吗?

转载 作者:可可西里 更新时间:2023-11-01 15:19:43 27 4
gpt4 key购买 nike

我有一堆如下代码:

int sign(MyEnum e)
{
switch(e)
{
case A:
case B:
return 1;
case C:
case D:
return -1;
default:
throw std::runtime_error("Invalid enum value");
}
}

int f(int a, int b, int c, MyEnum e)
{
const int sign = sign(e);

const int x = a * b - sign * c;
const int y = a + sign * c;

return x / y;
}

这里的算法只是一个例子。实际代码更复杂,但要点是 sign 是 -1 或 1,具体取决于枚举值,我们做了一堆计算,其中各种东西乘以 sign。 (编辑:枚举值在编译时未知。)

我希望优化此代码,就好像我编写了如下内容一样:

  int f(int a, int b, int c, MyEnum e)
{
switch(e)
{
case A:
case B:
{
const int x = a * b - c;
const int y = a + c;

return x / y;
}
case C:
case D:
{
const int x = a * b + c;
const int y = a - c;

return x / y;
}
default:
throw new std::runtime_error("Invalid enum value");
}
}

当然,我实际上并不想编写所有这样的代码,因为这是测试和维护的噩梦。

使用 Compiler Explorer,看起来 sign 中的异常可能是这里的问题;如果我有“默认”案例返回,比如说,-1,那么我就得到了我想要的。但我希望这里一些安全。

问题:

  1. 是否存在抛出异常阻止(或阻止编译器使用)此优化的根本原因?
  2. 看起来在 -O3 处编译此方法会生成该方法的两个克隆,其中一个执行我想要的操作,尽管我不知道实际会运行哪个。我可以为此提供提示吗?
  3. 我不知道我是否想在 -O3 编译所有。我可以只对特定代码块进行优化,还是鼓励编译器进行优化?
  4. 是否有一些花哨的模板元编程技巧或我可以用来编写看起来像第一个 block 但生成的代码看起来像第二个 block 的代码?
  5. 对于我正在尝试做的事情还有其他建议吗?

编辑:因为我(显然)不理解手头的所有问题,所以我可能没有给它起一个好标题。如果您知道自己在做什么,请随时进行编辑。

最佳答案

这里有一个替代方案:

template <int sign>
int f(int a, int b, int c)
{
const int x = a * b - sign * c;
const int y = a + sign * c;

return x / y;
}


int f(int a, int b, int c, MyEnum e)
{
const int sign = sign(e);
if (sign == 1) return f<1>(a, b, c);
else return f<-1>(a, b, c);
}

通过这种方式,您可以保持所需的安全性(以异常的形式),然后将结果信息转换为编译器可用于优化的编译时值。

作为Chris在评论中指出,如果 sign 仅用于切换 c 的符号,您可以完全摆脱模板,只需翻转 c 打电话时的手势:

int f(int a, int b, int c)
{
const int x = a * b - c;
const int y = a + c;

return x / y;
}


int f(int a, int b, int c, MyEnum e)
{
const int sign = sign(e);
if (sign == 1) return f(a, b, c);
else return f(a, b, -c);
}

关于c++ - 我可以鼓励 g++ 内联一个返回符号的开关吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57061181/

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