C# 的 Math 类仅以 double 形式执行根和幂。如果我在我的 Math2 课程中添加基于浮点数的平方根和幂函数,各种事情可能会更快一些(今天是放松的一天,我发现优化很放松)。
所以 - 我不必担心许可的快速平方根和幂函数,plskthx。或者可以让我到达那里的链接。
我认为没有任何软件方法可以与硬件指令竞争平方根这一点是不言而喻的。唯一的困难是 .NET 不像 C 代码的内联汇编器时代那样让我们直接控制硬件。
让我们首先讨论一个通用的 x86 硬件前景。
浮点 x86 指令 FSQRT 确实具有三种精度:单精度、双精度和扩展精度(80 位 FP 寄存器的本机精度),单精度与双精度的时序缩短 25-40%。请参阅此处了解 32 位 x86 指令。
这听起来像是一个很大的机会,但它只有十几个时钟左右。除非您能够仔细管理从函数调用到返回值的代码,否则这种节省很容易在开销中丢失。托管 C++ 听起来(正如 Marcelo Cantos 所建议的)比 C# 更实用。
注意:FSQRT 的时序与那些 FDIV 相同,它在 Intel 架构中共享一个执行单元,因此有一个共同的延迟。
在 SSE SIMD 指令的方向上可能存在专门的 C# 代码的更好机会,其中硬件允许并行执行多达 4 个单精度平方根。多年来一直缺少对此的 JIT 编译器支持,但这里有一些关于当前开发的线索。
英特尔已经介入(2010 年 12 月 15 日),看到 .NET Framework 4 没有对 SIMD 做任何事情:
甚至在此之前,Mono 项目在 Mono 2.2 中添加了对 SIMD 的 JIT 支持:
最近在这里提出了从 MS C# 调用 Mono 的 SIMD 支持的可能性:
[从 Microsoft .net 调用 mono c# 代码? - 堆栈溢出]
一个较早的问题也解决了(尽管没有表现出太多的爱!)如何安装 Mono 的 SIMD 支持:
应该看看这个链接:
http://www.codecodex.com/wiki/Calculate_an_integer_square_root
有很多不同语言的快速算法。
前任:
// Finds the integer square root of a positive number
public static int Isqrt(int num) {
if (0 == num) { return 0; } // Avoid zero divide
int n = (num / 2) + 1; // Initial estimate, never low
int n1 = (n + (num / n)) / 2;
while (n1 < n) {
n = n1;
n1 = (n + (num / n)) / 2;
} // end while
return n;
} // end Isqrt()
但还有更多,一些 C/C++ 应该是最快的,或者他们声称。
对于 POW 算法检查,我在这里找到了这个,以及如何使用该算法的说明,从更简单的算法开始。
private double Power(double a, int b) {
if (b<0) {
throw new ApplicationException("B must be a positive integer or zero");
}
if (b==0) return 1;
if (a==0) return 0;
if (b%2==0) {
return Power(a*a, b/2);
} else if (b%2==1) {
return a*Power(a*a,b/2);
}
return 0;
}
维基百科有一篇关于平方根计算的广泛文章: http ://en.wikipedia.org/wiki/Methods_of_computing_square_roots
计算 x 的 y 次方更简单: http ://www.osix.net/modules/article/?id=696
我喜欢这种带有麻点的计算器方式:
......但老实说,我不知道它是否很快。
可能最简单的方法是在托管 C++ 中实现浮动版本。这是否会比烘焙的双重版本更快,我不能说。