为什么java单精度要f_为什么快速反平方根如此奇怪和慢Java?
我试图在
java上实现
Fast Inverse Square Root,以加速向量规范化.然而,当我在Java中实现单精度版本时,我首先得到与1F /(float)Math.sqrt()相同的速度,然后快速下降到一半的速度.这是有趣的,因为当Math.sqrt使用(我推测)一个本地方法时,这涉及浮点除法,我听说的很慢.我的代码用于计算数字如下:
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;
}
使用我编写的一个简短的程序来迭代每1600万次,然后聚合结果,并重复,我得到如下结果:
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()
我一直得到两者的速度大致相同的数字,随后是一个迭代,其中快速逆平方根保存了1F / Math.sqrt()所需的大约60%的时间,然后是几次迭代,大约是两次快速反向平方根作为控件运行.我很困惑为什么FISR会从Same – >快60% – >每次运行我的程序都会慢100%.
编辑:以上数据是在eclipse中运行的.当我用javac / java运行程序时,我得到完全不同的数据:
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:经过几次回应,好像几次迭代后速度稳定下来,但稳定的数字是非常不稳定的.任何人都知道为什么?
这是我的代码(不完全简洁,但这里是整个事情):
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();
}
}
为什么java单精度要f_为什么快速反平方根如此奇怪和慢Java?相关推荐
- 穿越Java - 基础篇 第一章 快速带你入门 | 第3节 Java语言发展史
主题:Java语言发展史 开发环境 更多干货 发展史 开发环境 基于:IntelliJ IDEA.Maven构建工具.JDK1.8.SpringBoot 2.3.4 .Spring4.3.28编写. ...
- 安卓逆向_21 --- Java层和so层的反调试( IDA 动态调试 JNI_OnLoad、init_array下断)
1. 安卓程序动态调试条件 安卓程序动态调试条件 ( 2个满足1个即可 ): 1. 在 AndroidMainfest.xml ---> application 标签下,设置或者添加属性 and ...
- [Swift]快速反向平方根 | Fast inverse square root
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...
- java 判断类型_如何快速入门Java编程学习(干货)
一.初识Java 1.生活中的程序: 从起床到教室上课的过程 穿衣打扮>起床>洗漱>出宿舍>>吃早餐>到教室 按照特定的顺序去完成某一件事的过程我们叫做生活中的程序 ...
- Java 诊断利器Arthas:快速入门
简介 Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱.在线排查问题,无需重启:动态跟踪Java代码:实时监控JVM状态. Arthas 支持JDK 6+,支持Li ...
- 超详细!apk安装包快速反编译,多种反编译及失败的解决方案(包含classes.dex的反编译,新增加快速反编译)
如要转载,请贴出原地址:https://blog.csdn.net/Nobody_else_/article/details/83996441 众所周知,我们开发所用的手机App安装包都是apk文件, ...
- apk反编译工具使用方法 使用APKEditor V1.8旗舰版快速反编译安卓apk软件
学习安卓开发经常需要分析别人的apk,通过了解别人怎么编写的代码从而快速提高自己的编程水平,所以就需要用到apk反编译软件将别人的apk文件反编译出来,这样就可以查看其代码了.反编译是一种程序逆向编译 ...
- Java基础-SSM之mybatis快速入门篇
Java基础-SSM之mybatis快速入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 其实你可能会问什么是SSM,简单的说就是spring mvc + Spring + m ...
- java fields是_一个快速生成R2.java中fields的插件
一个快速生成R2.java中fields的插件 项目地址:github.com/JeasonWong/- 介绍 在子 module 中使用 ButterKnife 时,如果想使用 ButterKnif ...
最新文章
- 网站图片如何优化才对排名有所提升呢?
- 使用JJWT实现JWT代码示例
- 更改一字段的全部字节的大小写
- ASP.NET MVC数据验证(上)
- 使用Cloudformation集成Spring Boot和EC2
- 为了让开发者写MaxCompute SQL更爽,DataWorks 增强SQL 编辑器功能
- 线性代数【14】线性变换 linear transformation
- java中怎样调用抽象类中的非抽象方法?(对原文做修改,加入一点自己理解)
- python--二叉树库函数
- 基于jquery鼠标点击图片翻开切换效果
- CMSampleBufferRef获取h264 char*数据及sps/pps
- mysql 配置root密码_Mysql安装与配置调优及修改root密码的方法
- 【OpenCV】基于图像处理和模式识别的火灾检测方法
- oracle查询语句中case when的使用
- Mac最好用的SSH工具———SecureCRT使用以及下载
- VIVADO 安装教程
- Ubuntu 14.04 LTS 安装 文泉驿微米黑 字体到android studio
- android背景图拉伸,解决android:background背景图片被拉伸问题
- Possible solution: - Disable offline mode and rerun the build
- Android G711编解码