首页 / 知识
关于Java:通过JNI更快的Math.exp()吗?
2023-04-15 13:44:00

faster Math.exp() via JNI?
我需要非常频繁地从Java计算 我只尝试了jni + C,但是它比纯java慢。 已经多次请求了此请求(请参见此处)。这是从此博客文章中复制的Math.exp()的近似值:
它基本上与具有2048个条目以及条目之间的线性插值的查找表相同,但是所有这些都带有IEEE浮点技巧。它比我的机器上的Math.exp()快5倍,但是如果使用-server进行编译,则差异可能很大。 +1以编写自己的exp()实现。也就是说,如果这确实是您应用程序中的瓶颈。如果您可以处理一些不准确性,则可以使用许多非常有效的指数估计算法,其中一些可以追溯到几个世纪以前。据我了解,即使对于必须返回"精确"结果的算法,Java的exp()实现也相当慢。 哦,不要害怕用纯Java编写该exp()实现。 JNI有很多开销,并且JVM有时甚至可以在C / C ++不能实现的情况下在运行时优化字节码。 使用Java。 另外,缓存exp的结果,然后您可以比重新计算更快地查找答案。
您还希望在C中包装任何循环调用 如果分批执行,则可能使它运行得更快。进行JNI调用会增加开销,因此您不想为需要计算的每个exp()都这样做。我尝试传递100个值的数组,并获取结果以查看它是否对性能有所帮助。 真正的问题是,这成为您的瓶颈吗?您是否已对应用程序进行了概要分析,并发现这是速度下降的主要原因?如果没有,我建议使用Java版本。尽量不要进行预优化,因为这只会导致开发速度变慢。您可能会花较长的时间解决可能不是问题的问题。 话虽如此,我认为您的测试给了您答案。如果jni + C较慢,请使用Java版本。
Commons Math3附带了优化版本:
Fabien运行了一些测试,发现它的速度几乎是
这是javadoc: 计算exp(x),函数结果几乎取整。对于输入值的99.9%,它将正确舍入为理论值,否则将有1 UPL误差。 方法:
精度:计算以63位精度完成,因此对于99.9%的输入值,应正确舍入结果,否则应小于1个ULP误差。 它可能不再相关,但是可以知道,在OpenJDK的最新版本中(请参见此处),应将Math.exp设为内在函数(如果您不知道这是什么,请在此处检查)。 这将使性能在大多数体系结构上无与伦比,因为这意味着Hotspot VM将在运行时用特定于处理器的exp实现代替对Math.exp的调用。您永远无法击败这些电话,因为它们针对架构进行了优化。
先验功能总是比加法或乘法慢得多,并且是众所周知的瓶颈。如果知道值在狭窄范围内,则可以简单地建立一个查找表(两个排序数组;一个输入,一个输出)。使用Arrays.binarySearch查找正确的索引,并使用[index]和[index + 1]处的元素插入值。
另一种方法是拆分数字。让我们以3.81并将其拆分为3 + 0.81。 现在为0.81。 0到1之间的所有值都以众所周知的指数级数快速收敛 1 + x + x ^ 2/2 + x ^ 3/6 + x ^ 4/24 ...等 尽可能多地考虑精度要求;不幸的是,如果x接近1,速度会变慢。假设您转到x ^ 4,则得到2.2445,而不是正确的2.2448
然后将结果2.781 ^ 3 = 20.08与2.781 ^ 0.81 = 2.2445相乘得到结果 根据您要完成的工作,有更快的exp算法。问题空间是否限制在特定范围内,您是否仅需要特定的分辨率,精度或准确性等? 如果您很好地定义了问题,则可能会发现您可以使用带有插值的表,例如,该表将使几乎所有其他算法无效。 您可以对exp应用哪些约束来获得性能折衷? -亚当 跨越JNI边界进行调用会产生一定的成本。 如果您也可以将调用exp()的循环也移到本机代码中,以便只有一个本机调用,那么您可能会得到更好的结果,但是我怀疑它会比纯Java解决方案快得多。 我不知道您的应用程序的详细信息,但是如果调用的可用参数集相当有限,则可以使用预先计算的查找表来加快Java代码的速度。 根据您的需求编写自己的。 例如,如果所有指数都是2的幂,则可以使用位移。如果您使用有限的范围或一组值,则可以使用查找表。如果不需要精确度,则可以使用不精确但速度更快的算法。
使用JNI只会带来一些开销,另请参见: 因此,正如其他人所建议的那样,尝试整理涉及使用JNI的操作。 使用JNI的问题是调用JNI涉及的开销。如今,Java虚拟机已进行了非常优化,并且对内置Math.exp()的调用已自动进行了优化,以直接调用C exp()函数,甚至可能对其进行了优化,使其成为直接的x87浮点程序集说明。 由于Java代码将通过即时(JIT)编译器编译为本地代码,因此实际上没有理由使用JNI来调用本地代码。 另外,您不应缓存输入参数为浮点实数的方法的结果。及时获得的收益将在使用的空间量上大量损失。 |
最新内容
相关内容
脚本linux上运行命令?
脚本linux上运行命令?,工具,代码,时间,密码,系统,环境,名字,位置,第三,下来,typescript脚本中怎样运行Linux命令?1、Script可用于记录当前用户linux运行命令的脚本?
linux运行命令的脚本?,系统,服务,工具,脚本,意外,技术,分析,文件,方法,命令,sh文件在linux下如何运行Linux下面运行 SH文件步骤如下:查看目录sh重启计算机命令linux?
重启计算机命令linux?,系统,工作,命令,服务,标准,设备,灵活,首要,意义,参数,Linux的重启命令有哪些1、在linux下一些常用的关机/重启命令有shulinux转发请求命令?
linux转发请求命令?,系统,工作,密码,网络,服务,信息,工具,项目,状态,标准,关于Linux下必须知道的11个网络命令有哪些1、Linux的网络命令比较多linux运行脚本时未找到命令?
linux运行脚本时未找到命令?,系统,信息,环境,软件,异常,官网,底部,电脑,平台,为什么说,linux无法找到脚本文件是什么意思?1、意思是:找不到执行linux运行脚本的命令?
linux运行脚本的命令?,系统,工具,代码,服务,脚本,状态,密码,环境,位置,暂停,linux下如何运行可执行文件1、file 文件名 可以查看文件类型:或者:linux计算机的命令?
linux计算机的命令?,系统,工作,信息,设备,技术,命令,网站,管理,灵活,基础,linux查看路径命令linux命令如果记不得,可以使用man命令来查看某个命linux命令行运行中断?
linux命令行运行中断?,连续,工作,系统,信息,程序,命令,设备,工具,网络,情况,Linux停止命令继续执行的方法是什么1、Linux 里有一些工具,可以脱vim运行linux命令?
vim运行linux命令?,系统,工作,信息,地址,命令,标准,时间,情况,工具,基础,linux系统中如何进入退出vim编辑器,方法及区别先按ESC,再输入冒号,在输linux下并行运行命令?
linux下并行运行命令?,系统,服务,工作,命令,环境,网络,暂停,文件,脚本,参数,linux多个用户同时执行命令会冲突吗不会冲突。解释:用户登录linuxjar运行命令linux?
jar运行命令linux?,项目,系统,平台,工具,上期,命令,选项,日志,文件名,目录,Linux下运行springboot项目jar包,启动日志输出教程1、创建一个名为jar运行命令linux?
jar运行命令linux?,项目,系统,平台,工具,上期,命令,选项,日志,文件名,目录,Linux下运行springboot项目jar包,启动日志输出教程1、创建一个名为