C# 通过指定小数位数提高 CPU 除法速度
C# Improving CPU Speed in Division, by specifying # of Decimal Places
这是关于优化 CPU 速度。我正在寻找纳秒增益。
基本设置:
double Result;
Result = (double) 1 / 3;
这给出“0.333333333333333”。我正在寻找的只是 4 个有效的小数位,而不是整个除法。因此,除法后四舍五入没有区别。 CPU 应该在到达小数点后第 4 位时停止处理该问题。
这是改进吗?
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不顺序计算结果位数。此外,CPU 使用二进制数进行运算,而不是像普通人那样使用十进制数。
不管怎样,程序员不能弄乱它们的内部结构:这些算法实际上内置在硬件中。
所以你不能"partially do"一个指令。
SSE 中有几个 low-precision 指令比完全精确的等效指令运行得更快:即倒数和 rsqrt。但它们只是一般规则的两个例外。通常,几乎所有指令都没有 low-precision 等价物。
的确,乘法比现代 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# 编译器的行为方式。此外,编译器可以轻松地用乘法 compile-time 常数整数代替除法。
这是关于优化 CPU 速度。我正在寻找纳秒增益。
基本设置:
double Result;
Result = (double) 1 / 3;
这给出“0.333333333333333”。我正在寻找的只是 4 个有效的小数位,而不是整个除法。因此,除法后四舍五入没有区别。 CPU 应该在到达小数点后第 4 位时停止处理该问题。
这是改进吗?
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不顺序计算结果位数。此外,CPU 使用二进制数进行运算,而不是像普通人那样使用十进制数。 不管怎样,程序员不能弄乱它们的内部结构:这些算法实际上内置在硬件中。 所以你不能"partially do"一个指令。
SSE 中有几个 low-precision 指令比完全精确的等效指令运行得更快:即倒数和 rsqrt。但它们只是一般规则的两个例外。通常,几乎所有指令都没有 low-precision 等价物。
的确,乘法比现代 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# 编译器的行为方式。此外,编译器可以轻松地用乘法 compile-time 常数整数代替除法。