RFR: 8276673: Optimize abs operations in C2 compiler [v4]
Fei Gao
fgao at openjdk.java.net
Fri Dec 17 09:08:24 UTC 2021
On Thu, 16 Dec 2021 10:31:00 GMT, Fei Gao <fgao at openjdk.org> wrote:
>>> > The PR optimizes abs operations in the C2 middle end. Can I have your review please?
>>>
>>> So what's the performance data before and after this patch? Does it also benefit on x86?
>>>
>>> It would be better to provide a jmh micro benchmark. Thanks.
>>
>> Thanks, @DamonFool . Yes, it's supposed to benefit all archs.
>> For example, here is the performance data on x86.
>>
>> Before the patch:
>> Benchmark (seed) Mode Cnt Score Error Units
>> MathBench.absConstantInt 0 thrpt 5 291960.380 ± 10724.572 ops/ms
>>
>> After the patch:
>> Benchmark (seed) Mode Cnt Score Error Units
>> MathBench.absConstantInt 0 thrpt 5 336271.533 ± 3778.210 ops/ms
>>
>> The jmh micro benchmark testcase has been added in the latest commit.
>
>> Hi @fg1417 ,
>>
>> Thanks for your update.
>>
>> Now I see that you are trying to optimize the following three abs() patterns:
>>
>> 1. Math.abs(-38)
>> 2. (char) Math.abs((char) c)
>> 3. Math.abs(0 - x)
>>
>> But did you see these code patterns in real programs? I'm a bit worried that we just improve the complexity of C2 with (almost) no performance gain in the real world. Thanks.
>
> Thanks for your review, @DamonFool . I really understand your concern.
>
> In terms of complexity, the change only involves AbsNode and doesn’t modify any other code part. I don’t think it will make C2 more complex.
>
> As for performance gain in the real world, as we all know, the ability of GVN to optimize a node often depends on the optimized result of its input nodes. For example, if the input node of one AbsNode is recognized as a constant after last round of GVN optimization, now, we can optimize abs(constant) to a simple constant value. Like C2 did in https://github.com/openjdk/jdk/blob/0bddd8af61b6c731f16b857c09de57ceefd72d06/src/hotspot/share/opto/subnode.cpp#L55, we may not see -(-x) or (x+y)-y in any java program directly, but it’s possible after C2 optimization. Whether the optimization to sub or to abs is trivial, low-cost but useful. Why not apply it :)
>
> Math.abs(-38) , (char) Math.abs((char) c) and Math.abs(0 - x) are just conformance testcases. As you said, maybe nobody writes these cases in the real world. These testcases are just simulating all possible scenarios that AbsNode may meet, to guarantee the correctness of the optimization.
>
> What do you think :)
>
> Thanks.
> > > Hi @fg1417 ,
> > > Thanks for your update.
> > > Now I see that you are trying to optimize the following three abs() patterns:
> > >
> > > 1. Math.abs(-38)
> > > 2. (char) Math.abs((char) c)
> > > 3. Math.abs(0 - x)
> > >
> > > But did you see these code patterns in real programs? I'm a bit worried that we just improve the complexity of C2 with (almost) no performance gain in the real world. Thanks.
> >
> >
> > Thanks for your review, @DamonFool . I really understand your concern.
> > In terms of complexity, the change only involves AbsNode and doesn’t modify any other code part. I don’t think it will make C2 more complex.
> > As for performance gain in the real world, as we all know, the ability of GVN to optimize a node often depends on the optimized result of its input nodes. For example, if the input node of one AbsNode is recognized as a constant after last round of GVN optimization, now, we can optimize abs(constant) to a simple constant value. Like C2 did in
> > https://github.com/openjdk/jdk/blob/0bddd8af61b6c731f16b857c09de57ceefd72d06/src/hotspot/share/opto/subnode.cpp#L55
> >
> > , we may not see -(-x) or (x+y)-y in any java program directly, but it’s possible after C2 optimization. Whether the optimization to sub or to abs is trivial, low-cost but useful. Why not apply it :)
> > Math.abs(-38) , (char) Math.abs((char) c) and Math.abs(0 - x) are just conformance testcases. As you said, maybe nobody writes these cases in the real world. These testcases are just simulating all possible scenarios that AbsNode may meet, to guarantee the correctness of the optimization.
> > What do you think :)
> > Thanks.
>
> Then, shall we also opt cases like `Math.abs(-1 * x)`, `Math.abs(x / (-1))`, and so on? Thanks.
Hi, @DamonFool .
Actually, the cases you listed above, `Math.abs(-1 * x)`, `Math.abs(x / (-1))`, are covered by the optimized pattern, `Math.abs(0-x)`.
In C2, `-1 * x` is going to be `0 – x` after GVN optimization in MulNode. C2 takes `-1 * x` as `0 – (1*x)` firstly, and Identity here, https://github.com/openjdk/jdk/blob/0bddd8af61b6c731f16b857c09de57ceefd72d06/src/hotspot/share/opto/mulnode.cpp#L50, will combine `1*x` to x. After that, `0 – x` matched the pattern that AbsNode can recognize. `Math.abs(x / (-1))` , too. As I mentioned before, the AbsNode optimization doesn’t work as a standalone pass and it’s combined very closely to its input nodes. Instruction sequence changes as GVN repeats and our ideal pattern may occur.
Your cases also help prove that these several patterns, like abs(0-x) and abs(positive_value), are very fundamental and common. That’s why we choose them.
Thanks.
-------------
PR: https://git.openjdk.java.net/jdk/pull/6755
More information about the hotspot-compiler-dev
mailing list