Java内在方法和本机方法之间有什么区别? [英] What is the difference between Java intrinsic and native methods?

查看:161
本文介绍了Java内在方法和本机方法之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java内在函数在各个地方都有提及(例如此处).我的理解是,这些是使用特殊本机代码处理的方法.这似乎类似于JNI方法,它也是本机代码的一部分.

有什么区别?

解决方案

JIT知道内在函数,因此它可以将相关的机器指令内联到正在JIT的代码中,并作为热循环的一部分对其进行优化. >

JNI函数是编译器的100%黑匣子,具有相当大的调用/返回开销(尤其是如果仅将其用于标量的话).

但是,即使只是对编译为x86-64 popcnt eax, ediint bitcount(unsigned x){ return __builtin_popcount(x); }之类的函数的调用; ret(x86-64 System V调用约定)(JIT编译器正在发出)的调用方仍必须假定所有被调用阻塞的寄存器都被破坏了.在x86-64上,这是大多数整数寄存器和所有FP/向量寄存器. (就像提前调用C ++编译器调用黑盒函数和内部函数的成本一样).但是我怀疑调用JNI函数的成本还包括一些额外的开销.

当然,对任何未知函数的调用都意味着,如果JIT编译器无法证明没有其他东西可以引用它们,则可能需要将寄存器中的变量同步到内存中. (转义分析.)

此外,内在函数意味着JVM 了解函数的功能,并可以通过该函数进行优化.例如在持续传播的情况下,它知道popcount(5)= 2个设置位.但是对于实际的JNI函数,它仍然必须调用它.除非有某种方法将函数声明为"pure",否则每个调用都是明显的副作用,因此它可以 CSE .

使用大量内联,编译时间常数并不罕见.

Java intrinsic functions are mentioned in various places (e.g. here). My understanding is that these are methods that handled with special native code. This seems similar to a JNI method which is also a block of native code.

What is the difference?

解决方案

The JIT knows about intrinsics, so it can inline the relevant machine instruction into the code it's JITing, and optimize around it as part of a hot loop.

A JNI function is a 100% black box for the compiler, with significant call/return overhead (especially if you use it for just a scalar).

But even if it were just a call to a function like int bitcount(unsigned x){ return __builtin_popcount(x); } that compiled to x86-64 popcnt eax, edi ; ret (x86-64 System V calling convention) the caller (which the JIT compiler is emitting) would still have to assume that all the call-clobbered registers were clobbered. On x86-64, that's most of the integer registers and all the FP/vector registers. (Just like the cost for an ahead-of-time C++ compiler for calling a black-box function vs. an intrinsic). But I suspect the cost for calling a JNI function includes some extra overhead on top of that.

And of course a call to any unknown function means that variables which were in registers might need to be synced to memory if the JIT compiler can't prove that nothing else has a reference to them. (Escape analysis.)

Plus, intrinsics mean the JVM understands what the function does, and can optimize through it. e.g. with constant propagation, it knows that popcount(5) = 2 set bits. But with an actual JNI function, it would still have to call it. And every call is a visible side-effect unless there's some way to declare the function as "pure" so it can CSE.

With heavy inlining, compile time constants are not rare.

这篇关于Java内在方法和本机方法之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆