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