为什么java单精度要f_为什么快速反平方根如此奇怪和慢Java?
我試圖在
java上實(shí)現(xiàn)
Fast Inverse Square Root,以加速向量規(guī)范化.然而,當(dāng)我在Java中實(shí)現(xiàn)單精度版本時(shí),我首先得到與1F /(float)Math.sqrt()相同的速度,然后快速下降到一半的速度.這是有趣的,因?yàn)楫?dāng)Math.sqrt使用(我推測(cè))一個(gè)本地方法時(shí),這涉及浮點(diǎn)除法,我聽說的很慢.我的代碼用于計(jì)算數(shù)字如下:
public static float fastInverseSquareRoot(float x){
float xHalf = 0.5F * x;
int temp = Float.floatToRawIntBits(x);
temp = 0x5F3759DF - (temp >> 1);
float newX = Float.intBitsToFloat(temp);
newX = newX * (1.5F - xHalf * newX * newX);
return newX;
}
使用我編寫的一個(gè)簡(jiǎn)短的程序來迭代每1600萬次,然后聚合結(jié)果,并重復(fù),我得到如下結(jié)果:
1F / Math.sqrt() took 65209490 nanoseconds.
Fast Inverse Square Root took 65456128 nanoseconds.
Fast Inverse Square Root was 0.378224 percent slower than 1F / Math.sqrt()
1F / Math.sqrt() took 64131293 nanoseconds.
Fast Inverse Square Root took 26214534 nanoseconds.
Fast Inverse Square Root was 59.123647 percent faster than 1F / Math.sqrt()
1F / Math.sqrt() took 27312205 nanoseconds.
Fast Inverse Square Root took 56234714 nanoseconds.
Fast Inverse Square Root was 105.895914 percent slower than 1F / Math.sqrt()
1F / Math.sqrt() took 26493281 nanoseconds.
Fast Inverse Square Root took 56004783 nanoseconds.
Fast Inverse Square Root was 111.392402 percent slower than 1F / Math.sqrt()
我一直得到兩者的速度大致相同的數(shù)字,隨后是一個(gè)迭代,其中快速逆平方根保存了1F / Math.sqrt()所需的大約60%的時(shí)間,然后是幾次迭代,大約是兩次快速反向平方根作為控件運(yùn)行.我很困惑為什么FISR會(huì)從Same – >快60% – >每次運(yùn)行我的程序都會(huì)慢100%.
編輯:以上數(shù)據(jù)是在eclipse中運(yùn)行的.當(dāng)我用javac / java運(yùn)行程序時(shí),我得到完全不同的數(shù)據(jù):
1F / Math.sqrt() took 57870498 nanoseconds.
Fast Inverse Square Root took 88206794 nanoseconds.
Fast Inverse Square Root was 52.421004 percent slower than 1F / Math.sqrt()
1F / Math.sqrt() took 54982400 nanoseconds.
Fast Inverse Square Root took 83777562 nanoseconds.
Fast Inverse Square Root was 52.371599 percent slower than 1F / Math.sqrt()
1F / Math.sqrt() took 21115822 nanoseconds.
Fast Inverse Square Root took 76705152 nanoseconds.
Fast Inverse Square Root was 263.259133 percent slower than 1F / Math.sqrt()
1F / Math.sqrt() took 20159210 nanoseconds.
Fast Inverse Square Root took 80745616 nanoseconds.
Fast Inverse Square Root was 300.539585 percent slower than 1F / Math.sqrt()
1F / Math.sqrt() took 21814675 nanoseconds.
Fast Inverse Square Root took 85261648 nanoseconds.
Fast Inverse Square Root was 290.845374 percent slower than 1F / Math.sqrt()
編輯2:經(jīng)過幾次回應(yīng),好像幾次迭代后速度穩(wěn)定下來,但穩(wěn)定的數(shù)字是非常不穩(wěn)定的.任何人都知道為什么?
這是我的代碼(不完全簡(jiǎn)潔,但這里是整個(gè)事情):
public class FastInverseSquareRootTest {
public static FastInverseSquareRootTest conductTest() {
float result = 0F;
long startTime, endTime, midTime;
startTime = System.nanoTime();
for (float x = 1F; x < 4_000_000F; x += 0.25F) {
result = 1F / (float) Math.sqrt(x);
}
midTime = System.nanoTime();
for (float x = 1F; x < 4_000_000F; x += 0.25F) {
result = fastInverseSquareRoot(x);
}
endTime = System.nanoTime();
return new FastInverseSquareRootTest(midTime - startTime, endTime
- midTime);
}
public static float fastInverseSquareRoot(float x) {
float xHalf = 0.5F * x;
int temp = Float.floatToRawIntBits(x);
temp = 0x5F3759DF - (temp >> 1);
float newX = Float.intBitsToFloat(temp);
newX = newX * (1.5F - xHalf * newX * newX);
return newX;
}
public static void main(String[] args) throws Exception {
for (int i = 0; i < 7; i++) {
System.out.println(conductTest().toString());
}
}
private long controlDiff;
private long experimentalDiff;
private double percentError;
public FastInverseSquareRootTest(long controlDiff, long experimentalDiff) {
this.experimentalDiff = experimentalDiff;
this.controlDiff = controlDiff;
this.percentError = 100D * (experimentalDiff - controlDiff)
/ controlDiff;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("1F / Math.sqrt() took %d nanoseconds.%n",
controlDiff));
sb.append(String.format(
"Fast Inverse Square Root took %d nanoseconds.%n",
experimentalDiff));
sb.append(String
.format("Fast Inverse Square Root was %f percent %s than 1F / Math.sqrt()%n",
Math.abs(percentError), percentError > 0D ? "slower"
: "faster"));
return sb.toString();
}
}
總結(jié)
以上是生活随笔為你收集整理的为什么java单精度要f_为什么快速反平方根如此奇怪和慢Java?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java mongodb save,Ja
- 下一篇: java中抽象类 接口_java中的抽象