【问题标题】:C# Improving CPU Speed in Division, by specifying # of Decimal PlacesC# 通过指定小数位数来提高除法中的 CPU 速度
【发布时间】:2023-03-06 18:12:01
【问题描述】:

这是关于优化 CPU 速度的。我正在寻找纳秒级增益。

基本设置:

double Result;
Result = (double) 1 / 3;

这给出“0.333333333333333”。我正在寻找的只是 4 个有效的小数位而不进行整个除法。因此,除法后的四舍五入没有区别。当他到达小数点后第四位时,CPU 应该停止处理问题。

这是一种改进吗?

int Num = (int) 1 * 10000 / 3;
double Result = Num / (double) 10000;

或者干脆

double Result = (int)(1*10000/3)/(double)10000

这样更快吗?即使再乘以 10000?

我希望 Math 方法有类似 Math.Divide(numerator,denominator,significantDecimalPlaces) 的东西。有什么建议吗?

【问题讨论】:

  • CPU 计算额外的位(在相同的固定类型内)不会“额外花费”。舍入是一个单独的问题,如果/根据需要,它会改变结果。 Does C# Compiler calculate math on constants? 读起来很有趣,可能是相关的。
  • (另外,归根结底,这类“优化”可能不相关。在极少数情况下,这可能很重要 - 并且代码可能不在 C# 中 - 它应该显示为性能热点。)
  • 对于整数除法,请参阅:libdivide.com - 它是 c++,但您可以导入 C#。然而,正如已经说过的那样,寻找热点是相当值得的。如果除法确实是问题所在,则可能还有其他优化方法。在不知道自己在做什么的情况下,很难提出建议……
  • @user2864740 特别适用于编译时间常数,如示例中所示:)。要求的标准推荐:horses

标签: c# performance optimization operators


【解决方案1】:

CPU 不会按顺序计算结果的位数。此外,CPU 使用二进制数,而不是像普通人那样使用十进制数。 无论如何,程序员不能乱搞他们的内部结构:这些算法实际上是内置在硬件中的。 所以你不能“部分做”一条指令。

SSE 中有几个低精度指令的运行速度比完全精确的指令要快得多:即倒数和 rsqrt。但它们只是一般规则的两个例外。一般来说,几乎所有指令都没有低精度等效项。

确实,在现代 CPU 上,乘法比除法快得多。因此,如果分母在除法之间没有变化,则应预先计算其倒数(即倒数),然后将所有分子乘以它。以向量归一化为例:

double x, y, z;  //input vector
double invLen = 1.0 / sqrt(x*x + y*y + z*z);
x *= invLen;  y *= invLen;  z *= invLen;

C++ 编译器通常不执行此类优化,因为根据 IEEE 浮点运算规则,a / b 和 a * (1/b) 可能略有不同。但是如果你打开 fast math 开关,他们就会这样做。我不确定默认情况下 C# 编译器的行为方式。此外,编译器很容易用乘法代替编译时常量整数的除法。

【讨论】:

  • 非常感谢!正是我想要的。另外,碰巧我有那个确切的设置......用一个常数除数改变变量。所以,感谢您扩展答案。以前,我主要依赖 link 。但这澄清了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-25
  • 2016-08-10
  • 2013-01-22
  • 2013-04-14
  • 2011-12-04
  • 1970-01-01
相关资源
最近更新 更多