RFR: 8007806: Need a Throwables performance counter (original) (raw)

Peter Levart peter.levart at gmail.com
Sat Feb 23 19:39:23 UTC 2013


Hi Nils,

If the counters are updated frequently from multiple threads, there might be contention/scalability issues. Instead of synchronization on updates, you might consider using atomic updates provided by sun.misc.Unsafe, like for example:

Index: jdk/src/share/classes/sun/misc/PerfCounter.java

--- jdk/src/share/classes/sun/misc/PerfCounter.java +++ jdk/src/share/classes/sun/misc/PerfCounter.java @@ -25,6 +25,8 @@

package sun.misc;

+import sun.nio.ch.DirectBuffer; + import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.LongBuffer; @@ -50,6 +52,8 @@ public class PerfCounter { private static final Perf perf = AccessController.doPrivileged(new Perf.GetPerfAction());

hotspot/src/share/vm/runtime/perfdata.hpp private final static int V_Constant = 1; @@ -59,12 +63,14 @@

  private final String name;
  private final LongBuffer lb;

@@ -79,23 +85,44 @@ /** * Returns the current value of the perf counter. */

Testing the PerfCounter.increment() method in a loop on multiple threads sharing the same PerfCounter instance, for example, on a 4-core Intel i7 machine produces the following results:

PerfCounter_increment: run duration: 5,000 ms, #of logical CPUS: 8

        1 threads, Tavg =     19.02 ns/op (? =   0.00 ns/op)
        2 threads, Tavg =    109.93 ns/op (? =   6.17 ns/op)
        3 threads, Tavg =    136.64 ns/op (? =   2.99 ns/op)
        4 threads, Tavg =    293.26 ns/op (? =   5.30 ns/op)
        5 threads, Tavg =    316.94 ns/op (? =   6.28 ns/op)
        6 threads, Tavg =    686.96 ns/op (? =   7.09 ns/op)
        7 threads, Tavg =    793.28 ns/op (? =  10.57 ns/op)
        8 threads, Tavg =    898.15 ns/op (? =  14.63 ns/op)

With the presented patch, the results are a little better:

PerfCounter_increment: run duration: 5,000 ms, #of logical CPUS: 8

Measure:

        1 threads, Tavg =      5.22 ns/op (? =   0.00 ns/op)
        2 threads, Tavg =     34.51 ns/op (? =   0.60 ns/op)
        3 threads, Tavg =     54.85 ns/op (? =   1.42 ns/op)
        4 threads, Tavg =     74.67 ns/op (? =   1.71 ns/op)
        5 threads, Tavg =     94.71 ns/op (? =  41.68 ns/op)
        6 threads, Tavg =    114.80 ns/op (? =  32.10 ns/op)
        7 threads, Tavg =    136.70 ns/op (? =  26.80 ns/op)
        8 threads, Tavg =    158.48 ns/op (? =   9.93 ns/op)

The scalability is not much better, but the raw speed is, so it might present less contention when used in real-world code. If you wanted even better scalability, there is a new class in JDK8, the java.util.concurrent.LongAdder. But that doesn't buy atomic "set()" - only "add()". And it can't update native-memory variables, so it could only be used for add-only counters and in conjunction with a background thread that would periodically flush the sum to the native memory....

Regards, Peter

On 02/08/2013 06:10 PM, Nils Loodin wrote:

It would be interesting to know the number of thrown throwables in the JVM, to be able to do some high level application diagnostics / statistics. A good way to put this number would be a performance counter, since it is accessible both from Java and from the VM.

http://bugs.sun.com/bugdatabase/viewbug.do?bugid=8007806 http://cr.openjdk.java.net/~nloodin/8007806/webrev.00/ Regards, Nils Loodin



More information about the core-libs-dev mailing list