【问题标题】:Is it meaningful to store the result of a trigonometric function call?存储三角函数调用的结果有意义吗?
【发布时间】:2023-03-19 08:50:01
【问题描述】:

假设我正在编写 rotate() 库的 rotate() 方法的实现。

vector2D rotate(const vector2D vector, const vector2D origin, float radians)
{
    // Implementation details
    return {x, y};
}

我可以将三角函数调用的结果存储在变量中,因此我不必多次调用它们:

float sr = sin(radians);
float cr = cos(radians);
float x = origin.x + (
    (vector.x - origin.x) * cr - (vector.y - origin.y) * sr
);
float y = origin.y + (
    (vector.x - origin.x) * sr + (vector.y - origin.y) * cr
);

或者我可以简单地写下我的意思

float x = origin.x + (
    (vector.x - origin.x) * cos(radians) - (vector.y - origin.y) * sin(radians)
);
float y = origin.y + (
    (vector.x - origin.x) * sin(radians) + (vector.y - origin.y) * cos(radians)
);
  • 每种情况的优缺点是什么?
  • 编译器是否优化了第二个示例中的开销?或者即使在 vector2D 库的情况下,多次调用 trig 函数的开销也微不足道?

【问题讨论】:

    标签: c++ compilation trigonometry compiler-optimization c++-standard-library


    【解决方案1】:

    第一个版本很可能是编译器在优化第二个版本时生成的代码。

    一些编译器可能知道sincos 是纯函数,它们总是为特定参数返回相同的值。但语言标准对此只字未提,因此我们无法确定。

    此外,在尝试像这样的本地优化之前,您可能会问自己是否经常调用此函数以成为应用程序的瓶颈。否则,可能不会注意到确切的速度差异。

    gcc 编译器将 sin 和 cos 映射到 __builtin_sin and __builtin_cos,因此它对这些函数有额外的了解,但我不知道优化器是否利用了这一点。

    【讨论】:

    • gcc 编译器将 sin 和 cos 映射到 __builtin_sin and __builtin_cos,因此它对这些函数有额外的了解,但我不知道优化器是否利用了这一点。
    • GCC 不仅保存了 sin/cos 的结果,还实际计算了both at the same time。可悲的是,Clang没有那么尖锐。另一件需要考虑的事情:如果你用双精度进行计算,生成的代码会少得多。
    • @Revolver_Ocelot “双打计算”是什么意思?在第二个示例中,“双倍”作为重复代码?
    • @Dundee 在double 中而不是float。我知道浮点数有很多有效用途(想到 GPU 计算或 SIMD 指令),并且在不了解您的情况的情况下,无法确定是否值得更改数据类型,因此“考虑”。
    • @Revolver_Ocelot:实际上,我正在编写的代码完全是模板化的,所以数据类型并不是我真正关心的问题。 (为了清楚问题,我只是将其删除)但是感谢您指出这一点。
    【解决方案2】:

    您还可以为vector.x - origin.xvector.y - origin.y 定义变量。如前所述,这不是性能问题,因为编译器无论如何都会实现这些优化,而是代码可读性问题。

    如果您创建这些附加变量,您还应该将它们声明为const,因为您不打算更改它们的值。

    对于使用这些“冗余”变量有不同的看法。如果我能为它们找到一个有意义的名字,我个人会使用它们。

    【讨论】:

    • @Dundee:不确定,您一直在询问利弊,我认为我在现有答案中添加了一些其他方面。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    相关资源
    最近更新 更多