【问题标题】:Why is square root such a slow operation?为什么平方根运算这么慢?
【发布时间】:2014-03-11 17:54:33
【问题描述】:

许多程序员警告我不要使用平方根函数,而是将数字提高到一半的幂。我的问题是双重的:

  1. 这样做有什么感知/实际性能优势?为什么更快?

  2. 如果真的更快,为什么还存在平方根函数?

【问题讨论】:

  • 提升到 1/2 也一样慢,它们都只是 exp(ln(x)/2)
  • 你的测试显示了什么?
  • 这听起来像“不要加减 1。相反,加负 1”
  • 您的第一条规则应该始终是编写清晰、可维护且有意义的代码。如果您没有性能问题,请不要担心性能。如果您确实有性能问题,那么第一步应该始终是配置您的应用程序。完成此操作并确定热点后,您就可以开始担心可以采取哪些措施来修复它们。如果您已经到了那个时候,那么将sqrt 换成pow 并直接发现您的情况变得多么糟糕,那么您将毫无问题。
  • J. 的 cmets 非常好。我希望可以给予信用。

标签: c# vb.net math operator-keyword square-root


【解决方案1】:

我做了一个简单的测试

  Stopwatch sw = new Stopwatch();

  sw.Start();

  Double s = 0.0;

  // compute 1e8 times either Sqrt(x) or its emulation as Pow(x, 0.5)
  for (Double d = 0; d < 1e8; d += 1)
    // s += Math.Sqrt(d);  // <- uncomment it to test Sqrt
    s += Math.Pow(d, 0.5); // <- uncomment it to test Pow

  sw.Stop();

  Console.Out.Write(sw.ElapsedMilliseconds);

我的工作站 (x64) 的(平均)结果是

  Sqrt:  950 ms 
  Pow:  5500 ms

如您所见,Sqrt(x) 比其模拟 Pow(x, 0.5) 更具体 5.5。所以这只是 另一个传说(至少在 C# 中)Sqrt 是那个慢的人应该更喜欢 Pow 替换

【讨论】:

  • 在测试(尤其是)数学函数时,通常也值得说明目标平台或同时测试x86x64。由于硬件实现通常非常不同,因此有时可能会出现令人惊讶的差异(尽管在这种情况下差异不大)。从那时起,我猜这个例子是x64。对于x86Pow 只是快一点(但仍比sqrt很多)。
  • 注:1亿次SLOWER操作需要5.5秒。 1亿次FAST运算不到一秒。您的代码将成为瓶颈,而不是这些函数调用。
  • @duffymo 这有点老生常谈。瓶颈总是在某个地方的“代码”中。但是,如果您碰巧将sqrt 替换为Pow 中会出现性能瓶颈,那么您不这样做会有所收获。
  • 当然瓶颈在某人的代码中。我的观点是,重要的更有可能出现在 OP 的代码中,而不是这些函数中。分析器不太可能说平方根函数会影响性能。
  • @duffymo 如果您需要每秒计算数百万平方根怎么办?在我的情况下,Sqrt 占用了超过 10% 的 cpu 时间,而且我什至还没有开始优化我的代码的其他部分,所以它只会增加......
【解决方案2】:

您必须了解每个功能是如何实现的才能回答问题。

平方根函数使用Newton's method迭代计算平方根。它二次收敛。没有什么能加快速度。

其他函数 exp() 和 ln(x) 的实现有其自身的收敛/复杂性问题。例如,可以将两者都实现为series sums。需要一定数量的术语才能保持足够的准确性。

如果这些功能碰巧在本机代码中实现,那么所有的赌注都将失败。这些可能比你写的任何东西都快。

了解这些可以让您做出明智的决定。我不会相信它,因为那些程序员“知道”答案。

除非您正在做密集的数值工作,否则我会说选择不会影响您的整体程序性能。最好避免进行微优化,除非您正在做严肃的大规模科学编程。

【讨论】:

  • 如果你正在做严肃的科学编程,那么你的算法的数值稳定性和避免catastrophic cancellation 可能与速度一样(甚至更重要)。
  • 在这种情况下,Sqrt 在硬件中实现的,适用于 x87 FPU(fsqrt - 32 位)和 SSE/SSE2(sqrtss, @987654327 @;sqrtsdsqrtpd - 64 位)。这些比Pow 等的软件实现要快得多。即使在x87 硬件上,它具有f2xm1fyl2x 等的实现,只需一次调用f2xm1(这将使您开始实现@ 987654334@) 几乎与完整的fsqrt 一样昂贵,而fyl2x 的长度是fsqrt 的三倍多。除非非常具体的边缘情况和聪明的算法,否则Pow 不可能更快。
猜你喜欢
  • 2020-01-19
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 2022-11-27
  • 2021-09-03
  • 1970-01-01
  • 2014-08-31
  • 2011-10-18
相关资源
最近更新 更多