【问题标题】:Is there a faster way of accomplishing this in c?有没有更快的方法在c中完成这个?
【发布时间】:2021-08-12 00:32:27
【问题描述】:

所以我有一个表示角度的变量值。我在代码中经常使用这个值进行操作,所以我还需要经常检查它的值是否还在 [-180, +180] 范围内。

目前,我正在使用这段代码:

if (value > 180)
    value -= 360;
else if (value < -180)
    value += 360;

有没有更快的方法来完成同样的事情?

【问题讨论】:

  • @2b-t 三元运算符应该如何更快做到这一点?!?请介意详细说明?只是代码行更少,并不意味着生成的汇编代码会更快,或者完全不同。
  • @2b-t “你应该如何让它更快?”你不是。试图比现代 c 或 c++ 编译器更聪明以在那里获得更高的性能,通常会惨败:-P
  • 如果value 大于 540 或小于 -540,您的代码将不起作用。 180 度有两种表示形式(180 和 -180),否则您可以使用涉及 %360 的表达式的一些变体(如果您真的希望它在 -180 到 180 的范围内,请进行大量调整)以使其正常工作输入值。
  • 您目前的基准测试结果是什么?您想具体优化哪种微架构(假设 x86)?我们是在谈论尺寸优化还是速度优化?
  • @2b-t “现代 C++ 编译器如此出色 bla bla bla”之所以被“抛出很多”的原因是这样的问题:人们认为他们可以以某种方式在他们的代码中撒上神奇的汇编或奇怪的编译器特定的功能使一系列基于比较的ifs “更快”。同时,他们没有参考框架来比较新的解决方案,他们的代码没有被分析以确保给定的序列实际上是一个瓶颈,或者性能“问题”不存在。

标签: c optimization


【解决方案1】:

将其转换为 alu 操作。所以跳过 if(blablabla) 一起使用一些东西(就在我的头顶)

val = (val % 180) * (-1 * (val<180||val>180);

val = (val%180) * (-1 * abs(val)>180);

嗯,不确定这是对的,而且有点笨拙,但你明白了。 (val180) 不是 if then 并且不会导致分支丢失或停顿,它是一个 alu 操作。

会更快吗?那要看。时间不同的版本找出来。

【讨论】:

  • 感谢您的回答!一定会试试这个!
  • 我试过 val = val - 360*(val > 180) + 360*(val
  • 无论哪种方式,这都是一个很好的技巧,可以放在你的工具包中,在像这样的简单情况下它是不确定的,但在其他情况下,如果 else 树变成一个不错的短 alu 操作,它可能会变得丑陋。
【解决方案2】:

您可以将角度保持在一个圆的 2 次方而不是度数的单位中,例如圆的 1/512th。然后屏蔽正确的位,就像value &amp;= 0x1ffu 一样,会将角度减小到区间 [0,一圈)。如果您需要保持一个围绕零的对称间隔,您可以将角度保持在圆的 1/65536th,将 value 保持为 16 位有符号整数,并确保您的编译器use 有一个更宽的 int 并定义了转换为要包装的 16 位有符号整数类型。

在后一种情况下,不需要显式减少;每次存储值时,角度都会减小。某些处理器的成本可能是免费的,而大多数处理器的成本可能很小。

【讨论】:

    【解决方案3】:

    我使用双打

    a = remainder( a, 360.0);
    

    由于那里有一个分区,它不太可能很快,但我发现它易于使用且清晰。

    我认为这将是一个奇怪的程序,其中归一化角度对总时间的贡献很大!

    【讨论】:

      【解决方案4】:

      您可以使用模运算符。

      如果值是整数类型:

      int normalize_angle_int(int val) {
          return (val + 540) % 360 - 180;
      }
      

      如果值是浮点类型:

      #include <math.h>
      
      double normalize_angle_double(double val) {
          return val - floor(val / 360.0 + 0.5) * 360.0;
      }
      

      如果参数可以低于-540,则整数公式必须迭代:

      int normalize_angle_int(int val) {
          return (val % 360 + 540) % 360 - 180;
      }
      

      【讨论】:

      • @EricPostpischil:除法很慢,但除以常数可以通过一些调整实现乘法。
      • 当然,虽然他们应该密切关注。
      猜你喜欢
      • 1970-01-01
      • 2015-02-10
      • 1970-01-01
      • 2020-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多