2010-10-20 13 views
1

我一直在运行som eprofile测试一个缓慢的代码区域。这是与Visual Studio 2008和.NET 2(完全修补)。 Haversine公式使用我的约32%的计算。这需要两个正弦,两个余弦,一个平方根和一个反正弦 - 全部使用标准的.NET Math库(即Math.Sin,Math.Asin,Math.Sqrt)。我已经能够轻松地缓存余弦 - 导致Haversine函数加速大约25-30%。__CIasin和Is Arcsine比.NET中的正弦要慢吗?

在配置文件中,我看到__CIasin_pentium4和__CIasin,除了人们发布的堆栈转储之外,它们都没有在Google上找到太多内容。 pentium4变体可以获得大约两倍的样本数量(包含和不包含)。我认为这是一个反正弦,但是它真的比正弦要贵得多吗?在配置文件中没有正弦信号,即使计算两倍也是如此。

这两个函数都是反正弦还是一个正弦?如果不是,他们代表什么?

是的我在互联网上看过各种文章和帖子,在这里看到快速正弦。我确实需要计算正弦的准确性,而不是查找表或截断泰勒级数。我正在使用Haversine来计算和/或比较地球表面的距离。 10米的准确度(我的应用程序的最低恕我直言)相当于约1/640000弧度。

速度的一个想法是多元化三角身份。虽然这会导致更多的trig函数,但它们只会依赖于单个终点,因此会变得可缓存。另一个是解开反正弦和我的比较的平方根。我认为后者有很大的改进余地,然而目前我正在试图理解什么是处理时间,以及__CIasin函数代表什么。

+1

因此,您正在使用Math.Sin()或外部数学库? – codymanix 2010-10-20 16:13:32

+1

是的,我正在使用标准的数学库例程 - Math.Sin,Math.Asin和Math.Sqrt。我没有在配置文件中看到平方根,但我确实看到这两个__CIasin函数 - 大概是从调用Math.Asin开始的? – winwaed 2010-10-20 18:42:16

回答

1

看起来像奔腾FPU有正弦和余弦(fsin和fcos)本机指令,但不是反正弦。因此,我所看到的__CIasin函数可能是arcsine的.NET实现,我知道它使用泰勒级数。这解释了速度的巨大差异,因此asin显示出来,但罪恶却没有。 (或者是cos或者sqrt) - 这些也是原生函数)。

我很久以前就编写了x86 FPU。很久以前,我认为它一定是8087--无论如何,那些日子里唯一存在的是一个局部切线!

因此,优化中的下一个工作就是在可能的情况下从Haversine展开反正弦和平方根。结果用于比比较(排序等)简单地大于/小于;并与“固定”值进行比较。在这两种情况下,应该可以拆开这些包装。例如。固定值变成平方(sin(fixed)),并与sqrt内部的值进行比较。

我仍然认为trig的身份可能是一个有用的优化,但它肯定会使代码复杂化并引入错误的可能性。

0

是的,当然是打开sqrt和arc-sine。反向三角函数几乎总是比前向反函数慢,因为前向三角函数通常在FPU中实现。