【发布时间】:2013-09-05 17:29:30
【问题描述】:
我从其他几份报告中读到,人们在简单的基本 JNI 调用中通常会在 4-80 ns 左右:
对于琐碎的本机方法,去年我发现在我的 Windows 桌面上平均调用 40 ns,在我的 Mac 桌面上平均调用 11 ns ..
来自Possible increase of performace using JNI?
但是 JNI 调用通常需要大约 30 ns ..
当我在 JNI 代码中调用简单方法时(简单我的意思是返回类型 int 的时间参数不超过一个参数),我得到的往返调用时间(使用 System.nanoTIme 测量)在 50,000- 80,000 纳秒。
如果我做一个虚拟机“热身”并在计时之前运行几百次调用,我仍然会得到大约 2000-4000 ns(低于 800-1000)。 (如上所述,我听说其他人报告
这是正常速度吗?是什么导致我的本机代码被调用这么慢?
更新:
JNIEXPORT jint JNICALL Java_com_snap2d_gl_RenderControl_correctGammaNative
(JNIEnv *env, jobject obj, jint pixel) {
return X2D_correctGamma(pixel, 1.0f);
}
其中 X2D_correctGamma(int,float) 是一种校正像素伽马值的方法(自发布以来我已经实现了本机代码)。
Java 基准测试:
for(int i = 0; i < 100; i++) {
long t1 = System.nanoTime();
correctGammaNative(0xFFF);
long t2 = System.nanoTime();
System.out.println(t2 - t1);
}
这是“热身”代码。大多数 println 在初始调用后读取 800-1000ns。
不幸的是,我可能不得不放弃它,因为它应该用于渲染,每秒调用数千次会将帧速率降低到 1 FPS。
系统信息:
在 JDK1.6.0_32(64 位)、JDK1.7.0_04(64 位)和 JRE1.7.0_10(32 位)上表现相似
Windows 7 64 位
16GB 内存
i7-3770 四核 CPU @ 3.4-3.9ghz
GNU GCC MinGW 编译器(32 位和 64 位)
【问题讨论】:
-
你的原生方法是做什么的?它只是返回参数,还是做更多的事情?
-
因此,“热身”可能是扫描 PATH、从文件系统中找到 DLL、将其加载到内存中然后动态调用本机函数所花费的时间。你能检查一下你的 PATH 环境变量有多长吗? 50/80ms 这不是很长的时间。我不觉得它特别慢:50-80 毫秒来查找和加载一个 DLL 还不错。不过,我希望后续调用的时间为 0-1 毫秒,因为您的方法正在执行 nothing。有没有需要转换的参数/返回值?
-
“原始海报”似乎很多其他人报告 0-100 ns...并且在频繁通话时加起来确实高出 10-20 倍。
-
你能显示你正在计时的代码块和你使用的计时方法吗?
-
您是否考虑过对整个图像而不是一次一个像素进行伽马校正?
标签: java c performance java-native-interface