英文:
Is it possible to write a Java program which executes the FMOV instruction in an AArch64 computer?
问题
根据“Arm Architecture Reference Manual Armv8, for Armv8-A architecture profile”,存在一条指令FMOV (scalar, immediate)
。指南中指出:“此指令将浮点立即常量复制到SIMD和FP目标寄存器”。
是否可以编写一个简单的Java程序在AArch64机器上执行此指令?另外,如何验证编写的程序是否执行了特定的指令?谢谢。
PS1:我正在使用Eclipse OpenJ9 VM(https://www.eclipse.org/openj9)。
PS2:由于javap
基于字节码,这不是我要找的。我还尝试了以下命令,但无法验证指令是否执行-
java -Xjit:verbose,vlog=<vlogfile_name> <class_name>
英文:
According to the "Arm Architecture Reference Manual Armv8, for Armv8-A architecture profile", there is an instruction FMOV (scalar, immediate)
. It is stated that "This instruction copies a floating-point immediate constant into the SIMD & FP destination register".
Is it possible to write a simple Java program that executes this instruction in an AArch64 machine? Also, how can I verify that the written program executes a particular instruction? Thanks.
PS1: I'm using Eclipse OpenJ9 VM (https://www.eclipse.org/openj9).
<br>PS2: As javap
is based on bytecode, it's not what I'm looking for. I also tried below commands, but was unable to verify the instruction execution-
java -Xjit:limit={<function_name>} -Xjit:verbose,vlog=<vlogfile_name> <class_name>
java -Xjit:verbose,vlog=<vlogfile_name> <class_name>
答案1
得分: 0
Reading the armv8 spec:
>The Floating-point move (register) instructions copy a scalar floating-point value from one register to another
register without performing any conversion.
Some of the Floating-point move (register) instructions overlap with the functionality provided by the Advanced
SIMD instructions DUP , INS , and UMOV . However, Arm recommends using the FMOV instructions when operating on
scalar floating-point data to avoid the creation of scalar floating-point code that depends on the availability of the
Advanced SIMD instruction set.
Table C3-64 shows the Floating-point move (register) instructions.
The spec suggests that this instruction is the only way to move from a floating point register to a general-purpose register if the listed SIMD instructions aren't available. So you need Java code that converts a float to an int without performing a conversion, and a processor that doesn't have SIMD support.
The de facto way to do this in Java seems to be Float.floatToIntBits
.
On my JVM install (HotSpot JDK 8u forest), this is implemented as a native function. This native function eventually reaches hotspot/src/share/vm/opto/library_call.cpp
, with the following code:
case vmIntrinsics::_floatToRawIntBits:
case vmIntrinsics::_floatToIntBits:
case vmIntrinsics::_intBitsToFloat:
case vmIntrinsics::_doubleToRawLongBits:
case vmIntrinsics::_doubleToLongBits:
case vmIntrinsics::_longBitsToDouble:
return inline_fp_conversions(intrinsic_id());
The definition of inline_fp_conversions
is in the same file, and as far as I can tell, it could output an FMOV
instruction.
Notably, MoveF2INode
is emitted, though this may end up calling native code instead of actually JIT'ing an FMOV
.
英文:
Reading the armv8 spec:
>The Floating-point move (register) instructions copy a scalar floating-point value from one register to another
register without performing any conversion.
Some of the Floating-point move (register) instructions overlap with the functionality provided by the Advanced
SIMD instructions DUP , INS , and UMOV . However, Arm recommends using the FMOV instructions when operating on
scalar floating-point data to avoid the creation of scalar floating-point code that depends on the availability of the
Advanced SIMD instruction set.
Table C3-64 shows the Floating-point move (register) instructions.
The spec suggests that this instruction is the only way to move from a floating point register to a general purpose register, if the listed SIMD instructions aren't available. So you need java code that converts a float to an int without performing a conversion, and a processor that doesn't have SIMD support.
The defacto way to do this in java seems to be Float.floatToIntBits
.
On my JVM install(hotspot jdk8u forest) this is implemented as a native function. This native function eventually reaches hotspot/src/share/vm/opto/library_call.cpp
, with the following code:
case vmIntrinsics::_floatToRawIntBits:
case vmIntrinsics::_floatToIntBits:
case vmIntrinsics::_intBitsToFloat:
case vmIntrinsics::_doubleToRawLongBits:
case vmIntrinsics::_doubleToLongBits:
case vmIntrinsics::_longBitsToDouble:
return inline_fp_conversions(intrinsic_id());
The definition of inline_fp_conversions
is in the same file and as far as I can tell could output a FMOV
instruction.
Notably MoveF2INode
is emited, though this may end up calling native code instead of actually JIT'ing an FMOV
.
I'm a little conflicted, since it appears this question could be a homework question. But if this is the answer homework-issuer is looking for it seems like a dumb homework question, so I'm fine with this answer existing.
答案2
得分: 0
虽然不能确定此指令是否在程序运行之前执行,但我们可以通过HotSpot Disassembler(hsdis)找出简单Java程序的执行指令以及与指令关联的操作码。要获取相应的操作码,首先需要生成一个日志文件。然后,通过使用此日志文件,需要生成一个跟踪文件以查找执行的操作码是什么,适用于'那个'特定程序。在这种情况下,最好将跟踪文件的生成限制在目标函数上。否则,文件会很大。
一个简单的Java程序带有这个语句- x = x*2.0F;
在一个循环中运行了一千万次,导致执行了这个指令。
英文:
Although it is not possible to be certain if this instruction will be executed before the program runs, we can find-out the executed instructions by HotSpot Disassembler (hsdis) and the opcodes associated with the instructions of a simple Java program. For getting the respective opcodes, first, a log file needs to be generated. Then, by using this log file, a trace file needs to be generated to find-out what the executed opcodes are for 'that' particular program. In this case, it is better to limit the generation of the trace file for the targeted function only. Because that would be a big file otherwise.
A simple Java program with this statement- x = x*2.0F;
running on a loop of 10 million times caused the execution of this instruction.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论