Any planing for comparison related performance enhancements ?
Ulf Zibis
Ulf.Zibis at gmx.de
Wed Jun 30 02:49:56 PDT 2010
Am 29.06.2010 15:06, schrieb Christian Thalinger:
> On Tue, 2010-06-29 at 13:53 +0200, Ulf Zibis wrote:
>
>> Is there some planing, if and when those RFE's would be implemented in
>> HotSpot compiler?
>>
> I don't know of anyone planing to work on these CRs in the near term.
> We are currently very busy working on other things.
>
>
Much thanks about sharing the state about current reality.
For the record I additionally ask, if someone could file three
additional RFEs concerning performance:
Since beginning of this year Sun's bug infrastructure lacks to process
issues against HotSpot compiler from outside Sun/Oracle.
See thread:
http://mail.openjdk.java.net/pipermail/web-discuss/2010-June/000112.html
Please let me know about the bug ID when available:
================================================================================
SYNOPSIS
Support benefit of conditional logical operators
DESCRIPTION
In a chain of conditional logical operators, the first exclusion should
run fastest, i.e. have least branches.
JUSTIFICATION
Programmer could control fast path.
EXPECTED
0x00b85347: cmp $0xd800,%ecx
0x00b8534d: jge 0x00b8535c
0x00b8534f: xor %eax,%eax
0x00b85351: add $0x8,%esp
0x00b85354: pop %ebp
0x00b85355: test %eax,0x390000 ; {poll_return}
0x00b8535b: ret
0x00b8535c: cmp $0xdc00,%ecx
0x00b85362: jge 0x00b8534f ;*if_icmplt
; -
java.lang.Character::isHighSurrogate at 3 (line 2795)
0x00b85364: mov $0x1,%eax ;*ireturn
; -
java.lang.Character::isHighSurrogate at 17 (line 2795)
0x00b85369: jmp 0x00b85351
ACTUAL
0x00b85347: cmp $0xd800,%ecx
0x00b8534d: jl 0x00b85357
0x00b8534f: cmp $0xdc00,%ecx
0x00b85355: jl 0x00b8535b ;*if_icmplt
; -
java.lang.Character::isHighSurrogate at 3 (line 2795)
0x00b85357: xor %eax,%eax
0x00b85359: jmp 0x00b85360
0x00b8535b: mov $0x1,%eax ;*ireturn
; -
java.lang.Character::isHighSurrogate at 17 (line 2795)
0x00b85360: add $0x8,%esp
0x00b85363: pop %ebp
0x00b85364: test %eax,0x390000 ; {poll_return}
0x00b8536a: ret
SOURCE
public static boolean isHighSurrogate(char ch) {
// return ch >= MIN_HIGH_SURROGATE && ch <= MAX_HIGH_SURROGATE;
return ch >= MIN_HIGH_SURROGATE && ch < MAX_HIGH_SURROGATE + 1;
}
WORKAROUND
================================================================================
SYNOPSIS
Consecutive equivalent comparisons should be merged
DESCRIPTION
Different isXyz() methods often compare on same boundary. If
consecutive, after HotSpot inlining one of those compares could be saved.
JUSTIFICATION
- performance
- memory usage
EXPECTED
0x00b86587: cmp $0xd800,%ecx
0x00b8658d: jl 0x00b865a6
0x00b8658f: cmp $0xdc00,%ecx
0x00b86595: jl 0x00b865aa ;*if_icmplt
; -
java.lang.Character::isHighSurrogate at 3 (line 2795)
; -
java.lang.Benchmark::isSurrogate at 1 (line 7)
0x00b86597: cmp $0xe000,%ecx
0x00b8659d: jge 0x00b865a6 ;*if_icmpge
; -
java.lang.Character::isLowSurrogate at 9 (line 2819)
; -
java.lang.Benchmark::isSurrogate at 13 (line 9)
0x00b8659f: mov $0x1,%eax
0x00b865a4: jmp 0x00b865af ;*if_icmplt
; -
java.lang.Character::isLowSurrogate at 3 (line 2819)
; -
java.lang.Benchmark::isSurrogate at 13 (line 9)
0x00b865a6: xor %eax,%eax
0x00b865a8: jmp 0x00b865af
0x00b865aa: mov $0x2,%eax ;*goto
; -
java.lang.Benchmark::isSurrogate at 21 (line 10)
0x00b865af: add $0x8,%esp
0x00b865b2: pop %ebp
0x00b865b3: test %eax,0x390000 ; {poll_return}
0x00b865b9: ret
ACTUAL
0x00b86587: cmp $0xd800,%ecx
0x00b8658d: jl 0x00b86597
0x00b8658f: cmp $0xdc00,%ecx
0x00b86595: jl 0x00b865b2 ;*if_icmplt
; -
java.lang.Character::isHighSurrogate at 3 (line 2795)
; -
java.lang.Benchmark::isSurrogate at 1 (line 7)
0x00b86597: cmp $0xdc00,%ecx
0x00b8659d: jl 0x00b865ae ;*if_icmplt
; -
java.lang.Character::isLowSurrogate at 3 (line 2819)
; -
java.lang.Benchmark::isSurrogate at 13 (line 9)
0x00b8659f: cmp $0xe000,%ecx
0x00b865a5: jge 0x00b865ae ;*if_icmpge
; -
java.lang.Character::isLowSurrogate at 9 (line 2819)
; -
java.lang.Benchmark::isSurrogate at 13 (line 9)
0x00b865a7: mov $0x1,%eax
0x00b865ac: jmp 0x00b865b7 ;*if_icmplt
; -
java.lang.Character::isLowSurrogate at 3 (line 2819)
; -
java.lang.Benchmark::isSurrogate at 13 (line 9)
0x00b865ae: xor %eax,%eax
0x00b865b0: jmp 0x00b865b7
0x00b865b2: mov $0x2,%eax ;*goto
; -
java.lang.Benchmark::isSurrogate at 21 (line 10)
0x00b865b7: add $0x8,%esp
0x00b865ba: pop %ebp
0x00b865bb: test %eax,0x390000 ; {poll_return}
0x00b865c1: ret
SOURCE
int n;
if (Character.isHighSurrogate(c))
n = 2;
else if (Character.isLowSurrogate(c))
n = 1;
else
n = 0;
WORKAROUND
================================================================================
SYNOPSIS
Transform comparisons against odd border to even border
DESCRIPTION
Compile
a <= 0x50FF
as
a < 0x5100
.
JUSTIFICATION
- allows merging of consecutive comarisons against same borders
- allows optimization on consecutive comarisons by comparison against
small 8-bit immediant operand after right shift
- if char, allows optimization by 8-bit comparison on high byte, if low
byte == 0
- saves memory footprint and should be faster
EXPECTED
0x00b86cc7: cmp $0xd800,%ecx
0x00b86ccd: jl 0x00b86cde ;*if_icmplt
; -
java.lang.Benchmark::isHighSurrogate1 at 3 (line 7)
; -
java.lang.Benchmark::isSurrogate1 at 1 (line 35)
0x00b86ccf: cmp $0xdc00,%ecx
0x00b86cd5: jge 0x00b86cde ;*if_icmpge
; -
java.lang.Benchmark::isHighSurrogate1 at 9 (line 7)
; -
java.lang.Benchmark::isSurrogate1 at 1 (line 35)
0x00b86cd7: mov $0x2,%eax
0x00b86cdc: jmp 0x00b86cf7 ;*if_icmplt
; -
java.lang.Benchmark::isHighSurrogate1 at 3 (line 7)
; -
java.lang.Benchmark::isSurrogate1 at 1 (line 35)
// Could be omitted:
// 0x00b86cde: cmp $0xdc00,%ecx
// 0x00b86ce4: jl 0x00b86cf5 ;*if_icmplt
// ; -
java.lang.Benchmark::isLowSurrogate1 at 3 (line 11)
// ; -
java.lang.Benchmark::isSurrogate1 at 13 (line 37)
0x00b86ce6: cmp $0xe000,%ecx
0x00b86cec: jge 0x00b86cf5 ;*if_icmpge
; -
java.lang.Benchmark::isLowSurrogate1 at 9 (line 11)
; -
java.lang.Benchmark::isSurrogate1 at 13 (line 37)
0x00b86cee: mov $0x1,%eax
0x00b86cf3: jmp 0x00b86cf7 ;*if_icmplt
; -
java.lang.Benchmark::isLowSurrogate1 at 3 (line 11)
; -
java.lang.Benchmark::isSurrogate1 at 13 (line 37)
0x00b86cf5: xor %eax,%eax ;*goto
; -
java.lang.Benchmark::isSurrogate1 at 21 (line 38)
==============================
0x00b85007: shr $0x8,%eax ;*iushr
; -
java.lang.Benchmark::isHighSurrogate2 at 3 (line 15)
; -
java.lang.Benchmark::isSurrogate2 at 1 (line 45)
0x00b8500a: cmp $0xd8,%al
0x00b8500c: jl 0x00______ ;*if_icmplt
; -
java.lang.Benchmark::isHighSurrogate2 at 7 (line 15)
; -
java.lang.Benchmark::isSurrogate2 at 1 (line 45)
0x00b8500e: cmp $0xdc,%al
0x00b85010: jge 0x00______ ;*if_icmpge
; -
java.lang.Benchmark::isHighSurrogate2 at 17 (line 15)
; -
java.lang.Benchmark::isSurrogate2 at 1 (line 45)
...
==============================
0x00b85007: cmp $0xd8,%ch
0x00b8500a: jl 0x00______ ;*if_icmplt
; -
java.lang.Benchmark::isHighSurrogate2 at 7 (line 15)
; -
java.lang.Benchmark::isSurrogate2 at 1 (line 45)
0x00b8500c: cmp $0xdc,%ch
0x00b8500f: jge 0x00______ ;*if_icmpge
; -
java.lang.Benchmark::isHighSurrogate2 at 17 (line 15)
; -
java.lang.Benchmark::isSurrogate2 at 1 (line 45)
...
ACTUAL
0x00b84dc7: cmp $0xd800,%ecx
0x00b84dcd: jl 0x00b84dd7
0x00b84dcf: cmp $0xdbff,%ecx
0x00b84dd5: jle 0x00b84df2 ;*if_icmplt
; -
java.lang.Character::isHighSurrogate at 3 (line 2794)
; -
java.lang.Benchmark::isSurrogate at 1 (line 25)
0x00b84dd7: cmp $0xdc00,%ecx
0x00b84ddd: jl 0x00b84dee ;*if_icmplt
; -
java.lang.Character::isLowSurrogate at 3 (line 2818)
; -
java.lang.Benchmark::isSurrogate at 13 (line 27)
0x00b84ddf: cmp $0xdfff,%ecx
0x00b84de5: jg 0x00b84dee ;*if_icmpgt
; -
java.lang.Character::isLowSurrogate at 9 (line 2818)
; -
java.lang.Benchmark::isSurrogate at 13 (line 27)
0x00b84de7: mov $0x1,%eax
0x00b84dec: jmp 0x00b84df7 ;*if_icmplt
; -
java.lang.Character::isLowSurrogate at 3 (line 2818)
; -
java.lang.Benchmark::isSurrogate at 13 (line 27)
0x00b84dee: xor %eax,%eax
0x00b84df0: jmp 0x00b84df7
0x00b84df2: mov $0x2,%eax ;*goto
; -
java.lang.Benchmark::isSurrogate at 21 (line 28)
==============================
0x00b85007: shr $0x8,%ecx ;*iushr
; -
java.lang.Benchmark::isHighSurrogate2 at 3 (line 15)
; -
java.lang.Benchmark::isSurrogate2 at 1 (line 45)
0x00b8500a: cmp $0xd8,%ecx
0x00b85010: jl 0x00b85021 ;*if_icmplt
; -
java.lang.Benchmark::isHighSurrogate2 at 7 (line 15)
; -
java.lang.Benchmark::isSurrogate2 at 1 (line 45)
0x00b85012: cmp $0xdc,%ecx
0x00b85018: jge 0x00b85021 ;*if_icmpge
; -
java.lang.Benchmark::isHighSurrogate2 at 17 (line 15)
; -
java.lang.Benchmark::isSurrogate2 at 1 (line 45)
0x00b8501a: mov $0x2,%eax
0x00b8501f: jmp 0x00b8503a ;*if_icmplt
; -
java.lang.Benchmark::isHighSurrogate2 at 7 (line 15)
; -
java.lang.Benchmark::isSurrogate2 at 1 (line 45)
0x00b85021: cmp $0xdc,%ecx
0x00b85027: jl 0x00b85038 ;*if_icmplt
; -
java.lang.Benchmark::isLowSurrogate2 at 7 (line 19)
; -
java.lang.Benchmark::isSurrogate2 at 13 (line 47)
0x00b85029: cmp $0xe0,%ecx
0x00b8502f: jge 0x00b85038 ;*if_icmpge
; -
java.lang.Benchmark::isLowSurrogate2 at 17 (line 19)
; -
java.lang.Benchmark::isSurrogate2 at 13 (line 47)
SOURCE
public class Benchmark {
static boolean isHighSurrogate1(char ch) {
// return ch >= Character.MIN_HIGH_SURROGATE && ch <=
Character.MAX_HIGH_SURROGATE;
return ch >= Character.MIN_HIGH_SURROGATE && ch <
Character.MAX_HIGH_SURROGATE + 1;
}
static boolean isLowSurrogate1(char ch) {
// return ch >= Character.MIN_LOW_SURROGATE && ch <=
Character.MAX_LOW_SURROGATE;
return ch >= Character.MIN_LOW_SURROGATE && ch <
Character.MAX_LOW_SURROGATE + 1;
}
static boolean isHighSurrogate2(char ch) {
return ch >>> 8 >= Character.MIN_HIGH_SURROGATE >>> 8
&& ch >>> 8 < Character.MAX_HIGH_SURROGATE + 1 >>> 8;
}
static boolean isLowSurrogate2(char ch) {
return ch >>> 8 >= Character.MIN_LOW_SURROGATE >>> 8
&& ch >>> 8 < Character.MAX_LOW_SURROGATE + 1 >>> 8;
}
static int isSurrogate(char c) {
int n;
if (Character.isHighSurrogate(c))
n = 2;
else if (Character.isLowSurrogate(c))
n = 1;
else
n = 0;
return n;
}
static int isSurrogate1(char c) {
int n;
if (isHighSurrogate1(c))
n = 2;
else if (isLowSurrogate1(c))
n = 1;
else
n = 0;
return n;
}
static int isSurrogate2(char c) {
int n;
if (isHighSurrogate2(c))
n = 2;
else if (isLowSurrogate2(c))
n = 1;
else
n = 0;
return n;
}
static int bmIsSurrogate() {
int n = 0;
for (int i=0; i<10000; i++)
for (char c='\uD000'; c<'\uE000'; c++) {
n += isSurrogate(c);
n += isSurrogate1(c);
n += isSurrogate2(c);
}
return n;
}
public static void main(String... args) {
System.out.println(bmIsSurrogate());
}
}
WORKAROUND
================================================================================
SYNOPSIS
Use as less bits as necessary
DESCRIPTION
Examples:
on
a = b & 0xFF00
only 8 bits shold be moved (mov %ah,%bh).
on
a = (b >> 8) & 0xFF
only 8 bits shold be moved and shift should be saved (mov %al,%bh).
on
a = (b & 0xFF00) + c
only 8 bits shold be added.
on
a = b & 0xFFFF0000
only 16 bits shold be moved.
on
a = (b >> 16) & 0xFFFF
only 16 bits shold be moved and shift should be saved.
etc...
JUSTIFICATION
- saves memory footprint and should be faster
EXPECTED
For comparisons:
on
if (a & 0xFF > 0x12)
use
cmp %al, 0x12
on
if (a & 0xFF00 >= 0x1200)
use
cmp %ah, 0x12
on
char a;
if (a <= 0x11FF)
use
cmp %ah, 0x12
jl
instead
cmp %ax, 0x11FF
jle
etc...
ACTUAL
SOURCE
WORKAROUND
================================================================================
Thanks,
-Ulf
More information about the hotspot-compiler-dev
mailing list