我一直在努力优化我的数字程序,并且遇到了一些神秘的问题。我循环执行数千个浮点运算的代码,其中1个调用pow
- 然而,该调用占用了5%的时间......这不一定是关键问题,但它很奇怪,所以我想了解发生了什么。
当我查找缓存未命中时,VS.NET 2010RC的分析器报告几乎所有缓存未命中都发生在std::pow
中......所以......那是什么?有更快的替代方案吗?我试过了powf
,但这只是稍快一些;它仍然导致异常缓存未命中数。
为什么像pow这样的基本功能会导致缓存未命中?
编辑: 这不是托管代码。启用了/Oi
内在函数,但编译器可以选择忽略它。用pow(x,y)
替换exp(y*log(x))
具有类似的性能 - 刚才所有缓存未命中都在日志函数中。
答案 0 :(得分:2)
是的..它很慢。至于为什么那些感觉更自信的人可以尝试解释。
想加快速度吗?在这里:http://martin.ankerl.com/2007/10/04/optimized-pow-approximation-for-java-and-c-c/
答案 1 :(得分:2)
您能否提供有关'x'以及评估战俘的环境的更多信息?
您所看到的可能是工作中的硬件预取程序。根据分析器的不同,不同汇编指令的“成本”分配可能不正确,在评估pow所需的长延迟指令时应该更频繁。
除此之外,我会使用像VTune / PTU这样的真正的分析器,而不是任何Visual Studio版本中可用的分析器。
答案 2 :(得分:1)
如果您的代码涉及一些繁重的数字运算,那么std::pow
消耗5%的运行时间我不会感到惊讶。许多数值运算都非常快,因此像std::pow
这样稍微慢一点的操作相对于其他已经很快的操作来说似乎需要更多的时间。 (这也可以解释为什么你没有看到很多改进转换为std::powf
。)
缓存未命中有点令人费解,如果没有更多数据,很难提供解释。一种可能性是,如果你的其他代码是如此内存密集以至于吞噬了所有分配的缓存,那么std::pow
对缓存未命中的所有冲击就不足为奇了。
答案 3 :(得分:1)
如果您将std::pow(var)
替换为其他功能,例如std::max(var, var)
,它是否还会占用5%?你还得到所有缓存未命中吗?
我猜不到准时,对缓存未命中是。计算能力比许多其他操作(你使用的是哪些?)慢。调用不在缓存中的代码将导致缓存未命中,无论它是哪个函数。