On 10/02/2014 08:42 PM, Vitaly Davidovich wrote:
AFIK, varargs (up to something like 64 args) should be eliminated by
EA. Peter, can you add another jmh test that uses varargs but doesn't
call into System.arraycopy but uses the hand rolled version like your
at method? I'm wondering if that makes EA not kick in.
Hm, here is a modified benchmark (I also eliminated repeatable
allocation of target array):
@State(Scope.Benchmark)
public class FillArrayTest {
private Object
a0 = new Object(),
a1 = new Object(),
a2 = new Object(),
a3 = new Object(),
a4 = new Object(),
a5 = new Object(),
a6 = new Object(),
a7 = new Object();
private Object[] target = new Object[8];
private static void fillWithArguments(Object[] a, int pos,
Object... args) {
System.arraycopy(args, 0, a, pos, args.length);
}
private static Object[] fillArray(
Integer pos, Object[] a,
Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7
) {
fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7);
return a;
}
private static void fillWithArgumentsCopyLoop(Object[] a, int pos,
Object... args) {
for (int i = 0; i < args.length; i++) {
a[i + pos] = args[i];
}
}
private static Object[] fillArrayCopyLoop(
Integer pos, Object[] a,
Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7
) {
fillWithArgumentsCopyLoop(a, pos, a0, a1, a2, a3, a4, a5, a6, a7);
return a;
}
private static Object[] fillArrayAlt(
Integer pos, Object[] a,
Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7
) {
int i = pos;
a[i++] = a0;
a[i++] = a1;
a[i++] = a2;
a[i++] = a3;
a[i++] = a4;
a[i++] = a5;
a[i++] = a6;
a[i++] = a7;
return a;
}
@Benchmark
public Object[] fillArray() {
return fillArray(0, target, a0, a1, a2, a3, a4, a5, a6, a7);
}
@Benchmark
public Object[] fillCopyLoop() {
return fillArrayCopyLoop(0, target, a0, a1, a2, a3, a4, a5, a6,
a7);
}
@Benchmark
public Object[] fillArrayAlt() {
return fillArrayAlt(0, target, a0, a1, a2, a3, a4, a5, a6, a7);
}
}
The results:
Benchmark Mode Samples Score Score
error Units
j.t.FillArrayTest.fillArray thrpt 8 76534019.978
3063590.310 ops/s
j.t.FillArrayTest.fillArrayAlt thrpt 8 141640280.270
7815152.038 ops/s
j.t.FillArrayTest.fillCopyLoop thrpt 8 82050640.406
4055652.247 ops/s
The fillCopyLoop seems a little faster. I don't know if this is because
of possible elimination of allocation. The fillArrayAlt is still almost
2x as fast.
Peter
Sent from my phone
On Oct 2, 2014 2:34 PM, "Peter Levart" <peter.lev...@gmail.com
<mailto:peter.lev...@gmail.com>> wrote:
On 10/02/2014 06:55 PM, Vladimir Ivanov wrote:
Small update:
http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/
<http://cr.openjdk.java.net/%7Evlivanov/8058892/webrev.01/>
Need to reorder initialization sequence in MHI.Lazy.
Initialized FILL_ARRAYS and ARRAYS are required for later MH
lookups.
Additional testing:
* jck (api/java_lang/invoke)
* jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa"
and COMPILE_THRESHOLD={0,30}
Best regards,
Vladimir Ivanov
Hi Vladimir,
I have a comment that does not directly pertain to the code
changes (the initialization of arrays) but to the sub-optimal
implementation of "fillArray" methods I noticed by the way. While
it is nice to use varargs "makeArray" helper method with "array"
methods to construct the array, the same strategy used with
"fillWithArguments" in "fillArray" methods makes a redundant array
that is then copied to target array and discarded. The redundant
copying has a price. Here's a benchmark (Aleksey, please bear with
me):
@State(Scope.Benchmark)
public class FillArrayTest {
private Object
a0 = new Object(),
a1 = new Object(),
a2 = new Object(),
a3 = new Object(),
a4 = new Object(),
a5 = new Object(),
a6 = new Object(),
a7 = new Object();
private static void fillWithArguments(Object[] a, int pos,
Object... args) {
System.arraycopy(args, 0, a, pos, args.length);
}
private static Object[] fillArray(
Integer pos, Object[] a,
Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7
) {
fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7);
return a;
}
private static Object[] fillArrayAlt(
Integer pos, Object[] a,
Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7
) {
int i = pos;
a[i++] = a0;
a[i++] = a1;
a[i++] = a2;
a[i++] = a3;
a[i++] = a4;
a[i++] = a5;
a[i++] = a6;
a[i++] = a7;
return a;
}
@Benchmark
public Object[] fillArray() {
return fillArray(0, new Object[8], a0, a1, a2, a3, a4, a5,
a6, a7);
}
@Benchmark
public Object[] fillArrayAlt() {
return fillArrayAlt(0, new Object[8], a0, a1, a2, a3, a4,
a5, a6, a7);
}
}
The results on my i7 with JMH arguments "-i 8 -wi 5 -f 1 -gc true":
Benchmark Mode Samples Score
Score error Units
j.t.FillArrayTest.fillArray thrpt 8 48601447.674
5414853.634 <tel:5414853.634> ops/s
j.t.FillArrayTest.fillArrayAlt thrpt 8 90044973.732
8713725 <tel:732%208713725>.735 ops/s
So fillArrayAlt is nearly twice as fast...
Regards, Peter
On 10/2/14, 7:52 PM, Vladimir Ivanov wrote:
http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/
<http://cr.openjdk.java.net/%7Evlivanov/8058892/webrev.00/>
https://bugs.openjdk.java.net/browse/JDK-8058892
Core j.l.i classes are preloaded during VM startup in
order to avoid
possible deadlock when accessing JSR292-related
functionality from
multiple threads. After LF sharing-related changes,
FILL_ARRAYS and
ARRAYS are initialized too early. It affects startup time
& footprint of
applications that don't use JSR292.
The fix is to move these fields into MHI.Lazy class, thus
delaying their
initialization to the first usage of JSR292 API.
Testing: failing test, manual (measured HelloWorld app
startup time;
compared -XX:+PrintCompilation logs)
Best regards,
Vladimir Ivanov
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net <mailto:mlvm-dev@openjdk.java.net>
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev