-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8290322: Optimize Vector.rearrange over byte vectors for AVX512BW targets. #9498
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back jbhateja! A progress list of the required criteria for merging this PR into |
/label add hotspot-compiler-dev |
@jatin-bhateja |
Webrevs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing tier1-3 passed.
@jatin-bhateja This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 81 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. My Cascade Lake server benefits from this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise looks good to me. Thanks.
src/hotspot/cpu/x86/x86.ad
Outdated
} else if (bt == T_BYTE && size_in_bits > 256 && !VM_Version::supports_avx512_vbmi()) { | ||
return false; // Implementation limitation | ||
} else if (bt == T_SHORT && size_in_bits > 256 && !VM_Version::supports_avx512bw()) { | ||
} else if (is_subword_type(bt) && size_in_bits > 256 && !VM_Version::supports_avx512bw()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not needed as a 512-bit subword type vector is only supported on avx512bw anyway.
@@ -5565,3 +5565,65 @@ void C2_MacroAssembler::udivmodL(Register rax, Register divisor, Register rdx, R | |||
} | |||
#endif | |||
|
|||
void C2_MacroAssembler::rearrange_bytes(XMMRegister dst, XMMRegister shuffle, XMMRegister src, XMMRegister xtmp1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use the same approach as that used for 256-bit vector. Something similar to:
vpshufb(xtmp1, src, shuffle); // All elements are at the correct place modulo 16
vpxor(dst, dst, dst);
vpslld(xtmp2, shuffle, 3); // Push the digit signifying the parity of 128-bit lane to the sign digit
vpcmpb(ktmp, xtmp2, dst, lt);
vshufi32x4(xtmp2, xtmp1, xtmp1, 0b10110001); // Shuffle the 128-bit lanes to get 1 - 0 - 3 - 2
vpblendmb(xtmp1, ktmp, xtmp1, xtmp2); // All elements are at the correct place modulo 32
vpslld(xtmp2, shuffle, 2); // Push the digit signifying the parity of 256-bit lane to the sign digit
vpcmpb(ktmp, xtmp2, dst, lt);
vshufi32x4(xtmp2, xtmp1, xtmp1, 0b01001110); // Shuffle the 128-bit lanes to get 2 - 3 - 0 - 1
vpblendmb(dst, ktmp, xtmp1, xtmp2); // All elements are at the correct place modulo 64
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, it is my bad, this should not work. Sorry for the noise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice work. I have some point suggestions which improves the performance further by ~20%. Please take a look.
vpshufb(xtmp3, xtmp3, shuffle, vlen_enc); | ||
evmovdqub(dst, ktmp2, xtmp3, false, vlen_enc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The avx512 version of vpshufb takes K register and merge as the input.
This can then be replaced by:
evpshufb(dst, ktmp2, xtmp3, shuffle, false, vlen_enc);
vpshufb(xtmp3, xtmp3, shuffle, vlen_enc); | ||
evmovdqub(xtmp4, ktmp2, xtmp3, false, vlen_enc); | ||
vporq(dst, dst, xtmp4, vlen_enc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be replaced by:
evpshufb(dst, ktmp2, xtmp3, shuffle, true, vlen_enc);
vpshufb(xtmp3, xtmp3, shuffle, vlen_enc); | ||
evmovdqub(xtmp4, ktmp2, xtmp3, false, vlen_enc); | ||
vporq(dst, dst, xtmp4, vlen_enc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be replaced by:
evpshufb(dst, ktmp2, xtmp3, shuffle, true, vlen_enc);
vpshufb(xtmp3, xtmp3, shuffle, vlen_enc); | ||
evmovdqub(xtmp4, ktmp2, xtmp3, false, vlen_enc); | ||
vporq(dst, dst, xtmp4, vlen_enc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be replaced by:
evpshufb(dst, ktmp2, xtmp3, shuffle, true, vlen_enc);
vpermq(xtmp3, src, 0x44, vlen_enc); | ||
vinserti64x4(xtmp3, xtmp3, xtmp3, 0x1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The evshuffi64x2 instruction could be used here:
evshuffi64x2(xtmp3, k0, src, src, 0x0, false, vlen_enc);
vpermq(xtmp3, src, 0x44, vlen_enc); | ||
vextracti64x4_high(xtmp3, xtmp3); | ||
vinserti64x4(xtmp3, xtmp3, xtmp3, 0x1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The evshuffi64x2 instruction could be used here:
evshuffi64x2(xtmp3, k0, src, src, 0xaa, false, vlen_enc);
vpermq(xtmp3, src, 0xEE, vlen_enc); | ||
vextracti64x4_high(xtmp3, xtmp3); | ||
vinserti64x4(xtmp3, xtmp3, xtmp3, 0x1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The evshuffi64x2 instruction could be used here:
evshuffi64x2(xtmp3, k0, src, src, 0xff, false, vlen_enc);
evpcmpb(ktmp2, k0, shuffle, xtmp5, Assembler::lt, true, vlen_enc); | ||
kandql(ktmp2, ktmp1, ktmp2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be replaced by:
evpcmpb(ktmp2, ktmp1, shuffle, xtmp5, Assembler::lt, true, vlen_enc);
evpcmpb(ktmp2, k0, shuffle, xtmp5, Assembler::lt, true, vlen_enc); | ||
kandql(ktmp2, ktmp1 , ktmp2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be replaced by:
evpcmpb(ktmp2, ktmp1, shuffle, xtmp5, Assembler::lt, true, vlen_enc);
evpcmpb(ktmp2, k0, shuffle, xtmp5, Assembler::lt, true, vlen_enc); | ||
kandql(ktmp2, ktmp1 , ktmp2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be replaced by:
evpcmpb(ktmp2, ktmp1, shuffle, xtmp5, Assembler::lt, true, vlen_enc);
You could also use ktmp1 as the destination in the above instruction and its use thereby remove the ktmp2 usage altogether.
With above suggestions, the rearrange_bytes() kernel would look something like below: // Compute a mask for shuffle vector by comparing indices with expression INDEX < 16, // Perform above steps with lane comparison expression as INDEX >= 16 && INDEX < 32 evpcmpb(ktmp1, k0, shuffle, xtmp2, Assembler::nlt, true, vlen_enc); // Perform above steps with lane comparison expression as INDEX >= 32 && INDEX < 48 // Perform above steps with lane comparison expression as INDEX >= 48 && INDEX < 64 The number of xtmp and ktmp registers could also be further reduced. |
evpcmpb(ktmp2, k0, shuffle, xtmp2, Assembler::lt, true, vlen_enc); | ||
kandql(ktmp2, ktmp1, ktmp2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sequence could be replaced by:
evpcmpb(ktmp2, ktmp1, shuffle, xtmp2, Assembler::lt, true, vlen_enc);
It could also be further improved to:
evpcmpb(ktmp1, ktmp1, shuffle, xtmp2, Assembler::lt, true, vlen_enc);
Thereby removing the need for ktmp2 altogether.
There are three instances of this in the algorithm.
Rest of the changes look good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sviswa7 for your comments.
/integrate |
Going to push as commit 38a8191.
Your commit was automatically rebased without conflicts. |
@jatin-bhateja Pushed as commit 38a8191. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
FTR, the latest version passed tier1-4 clean. |
@jatin-bhateja Could not automatically backport
Please fetch the appropriate branch/commit and manually resolve these conflicts by using the following commands in your personal fork of openjdk/jdk19u. Note: these commands are just some suggestions and you can use other equivalent commands you know.
Once you have resolved the conflicts as explained above continue with creating a pull request towards the openjdk/jdk19u with the title |
Hi All,
Currently re-arrange over 512bit bytevector is optimized for targets supporting AVX512_VBMI feature, this patch generates efficient JIT sequence to handle it for AVX512BW targets. Following performance results with newly added benchmark shows
significant speedup.
System: Intel(R) Xeon(R) Platinum 8280 CPU @ 2.70GHz (CascadeLake 28C 2S)
Kindly review and share your feedback.
Best Regards,
Jatin
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/9498/head:pull/9498
$ git checkout pull/9498
Update a local copy of the PR:
$ git checkout pull/9498
$ git pull https://git.openjdk.org/jdk pull/9498/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 9498
View PR using the GUI difftool:
$ git pr show -t 9498
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/9498.diff