RFR: 8318225: RISC-V: C2 UModI
Hamlin Li
mli at openjdk.org
Fri Oct 27 10:07:32 UTC 2023
On Fri, 27 Oct 2023 09:15:11 GMT, Hamlin Li <mli at openjdk.org> wrote:
> Hi,
> Can you review the change to add intrinsic for UModI and UModL?
> ( This is a quite similar patch to https://github.com/openjdk/jdk/pull/16346, which addresses UDivI and UDivL, so for the performance consideration please also check the discussion in that pr. )
> Thanks!
>
>
> ## Tests
>
> ### Functionality
> Run tests successfully found via `grep -nr test/jdk/ -we remainderUnsigned` and `grep -nr test/hotspot/ -we remainderUnsigned`
>
> ### Performance
>
> #### Long
> **NOTE: for positive divisor, it's the common case; for negative divisor, it's a rare case**
>
> **Before**
>
> LongDivMod.testRemainderUnsigned 1024 mixed avgt 10 21222.911 ± 57.735 ns/op
> LongDivMod.testRemainderUnsigned 1024 positive avgt 10 28841.429 ± 6.294 ns/op
> LongDivMod.testRemainderUnsigned 1024 negative avgt 10 7733.038 ± 3.856 ns/op
>
>
> **After**
>
> LongDivMod.testRemainderUnsigned 1024 mixed avgt 10 22666.448 ± 34.986 ns/op
> LongDivMod.testRemainderUnsigned 1024 positive avgt 10 15967.846 ± 24.805 ns/op
> LongDivMod.testRemainderUnsigned 1024 negative avgt 10 29507.865 ± 20.593 ns/op
>
>
> #### Integer
> **Before**
>
> IntegerDivMod.testRemainderUnsigned 1024 mixed avgt 10 23396.475 ± 24.065 ns/op
> IntegerDivMod.testRemainderUnsigned 1024 positive avgt 10 16796.796 ± 3.389 ns/op
> IntegerDivMod.testRemainderUnsigned 1024 negative avgt 10 30159.407 ± 6.716 ns/op
>
>
> **After**
>
> IntegerDivMod.testRemainderUnsigned 1024 mixed avgt 10 23216.710 ± 14.351 ns/op
> IntegerDivMod.testRemainderUnsigned 1024 positive avgt 10 16621.374 ± 3.203 ns/op
> IntegerDivMod.testRemainderUnsigned 1024 negative avgt 10 30002.088 ± 41.212 ns/op
Good find.
Let me try to explain.
For l.l.Long, remainderUnsigned has a quick path for negative divisor (This was discussed in https://github.com/openjdk/jdk/pull/16346), it's much quicker than the case of positive divisor.
For j.l.Integer
public static int remainderUnsigned(int dividend, int divisor) {
// In lieu of tricky code, for now just use long arithmetic.
return (int)(toUnsignedLong(dividend) % toUnsignedLong(divisor));
}
it will call Long's rem, and the value of divisor passed to Long rem will be positive in the sense of Long.
To verify this, you can compare the Long's rem data before the patch, positive one is much lower than negative one.
LongDivMod.testRemainderUnsigned 1024 positive avgt 10 28841.429 ± 6.294 ns/op
LongDivMod.testRemainderUnsigned 1024 negative avgt 10 7733.038 ± 3.856 ns/op
Hope this answers your question.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/16394#issuecomment-1782646419
More information about the hotspot-dev
mailing list