RFC: C2 Object Initialization - Using XMM/YMM registers
Vladimir Kozlov
vladimir.kozlov at oracle.com
Thu Apr 5 18:08:57 UTC 2018
Good suggestion, Rohit
I created new RFE. Please add you suggestion and performance data there:
https://bugs.openjdk.java.net/browse/JDK-8201193
Thanks,
Vladimir
On 4/5/18 12:19 AM, Rohit Arul Raj wrote:
> Hi All,
>
> I was going through the C2 object initialization (zeroing) code based
> on the below bug entry:
> https://bugs.openjdk.java.net/browse/JDK-8146801
>
> Right now, for longer lengths we use "rep stos" instructions on x86. I
> was experimenting with using XMM/YMM registers (on AMD EPYC processor)
> and found that they do improve performance for certain lengths:
>
> For lengths > 64 bytes - 512 bytes : improvement is in the range of 8% to 44%
> For lengths > 512bytes : some lengths show slight
> improvement in the range of 2% to 7%, others almost same as "rep stos"
> numbers.
>
> I have attached the complete performance data (data.txt) for reference .
> Can we add this as an user option similar to UseXMMForArrayCopy?
>
> I have used the same test case as in
> (http://cr.openjdk.java.net/~shade/8146801/benchmarks.jar) with
> additional sizes.
>
> Initial Patch:
> I haven't added the check for 32-bit mode as I need some help with the
> code (description given below the patch).
> The code is similar to the one used in array copy stubs (copy_bytes_forward).
>
> diff --git a/src/hotspot/cpu/x86/globals_x86.hpp
> b/src/hotspot/cpu/x86/globals_x86.hpp
> --- a/src/hotspot/cpu/x86/globals_x86.hpp
> +++ b/src/hotspot/cpu/x86/globals_x86.hpp
> @@ -150,6 +150,9 @@
> product(bool, UseUnalignedLoadStores, false, \
> "Use SSE2 MOVDQU instruction for Arraycopy") \
> \
> + product(bool, UseXMMForObjInit, false, \
> + "Use XMM/YMM MOVDQU instruction for Object Initialization") \
> + \
> product(bool, UseFastStosb, false, \
> "Use fast-string operation for zeroing: rep stosb") \
> \
> diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp
> b/src/hotspot/cpu/x86/macroAssembler_x86.cpp
> --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp
> +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp
> @@ -7106,6 +7106,56 @@
> if (UseFastStosb) {
> shlptr(cnt, 3); // convert to number of bytes
> rep_stosb();
> + } else if (UseXMMForObjInit && UseUnalignedLoadStores) {
> + Label L_loop, L_sloop, L_check, L_tail, L_end;
> + push(base);
> + if (UseAVX >= 2)
> + vpxor(xmm10, xmm10, xmm10, AVX_256bit);
> + else
> + vpxor(xmm10, xmm10, xmm10, AVX_128bit);
> +
> + jmp(L_check);
> +
> + BIND(L_loop);
> + if (UseAVX >= 2) {
> + vmovdqu(Address(base, 0), xmm10);
> + vmovdqu(Address(base, 32), xmm10);
> + } else {
> + movdqu(Address(base, 0), xmm10);
> + movdqu(Address(base, 16), xmm10);
> + movdqu(Address(base, 32), xmm10);
> + movdqu(Address(base, 48), xmm10);
> + }
> + addptr(base, 64);
> +
> + BIND(L_check);
> + subptr(cnt, 8);
> + jccb(Assembler::greaterEqual, L_loop);
> + addptr(cnt, 4);
> + jccb(Assembler::less, L_tail);
> + // Copy trailing 32 bytes
> + if (UseAVX >= 2) {
> + vmovdqu(Address(base, 0), xmm10);
> + } else {
> + movdqu(Address(base, 0), xmm10);
> + movdqu(Address(base, 16), xmm10);
> + }
> + addptr(base, 32);
> + subptr(cnt, 4);
> +
> + BIND(L_tail);
> + addptr(cnt, 4);
> + jccb(Assembler::lessEqual, L_end);
> + decrement(cnt);
> +
> + BIND(L_sloop);
> + movptr(Address(base, 0), tmp);
> + addptr(base, 8);
> + decrement(cnt);
> + jccb(Assembler::greaterEqual, L_sloop);
> +
> + BIND(L_end);
> + pop(base);
> } else {
> NOT_LP64(shlptr(cnt, 1);) // convert to number of 32-bit words
> for 32-bit VM
> rep_stos();
>
>
> When I use XMM0 as a temporary register, the micro-benchmark crashes.
> Saving and Restoring the XMM0 register before and after use works
> fine.
>
> Looking at the "hotspot/src/cpu/x86/vm/x86.ad" file, XMM0 as with
> other XMM registers has been mentioned as Save-On-Call registers and
> on Linux ABI, no register is preserved across function calls though
> XMM0-XMM7 might hold parameters. So I assumed using XMM0 without
> saving/restoring should be fine.
>
> Is it incorrect use XMM* registers without saving/restoring them?
> Using XMM10 register as temporary register works fine without having
> to save and restore it.
>
> Please let me know your comments.
>
> Regards,
> Rohit
>
More information about the hotspot-dev
mailing list