ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/jsr166e/DoubleAdderDemo.java
Revision: 1.2
Committed: Tue Aug 2 18:22:20 2011 UTC (12 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.1: +6 -6 lines
Log Message:
whitespace

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 import java.util.concurrent.Phaser;
8 import java.util.concurrent.ExecutorService;
9 import java.util.concurrent.Executors;
10 import java.util.concurrent.atomic.AtomicLong;
11 import jsr166e.DoubleAdder;
12
13 public class DoubleAdderDemo {
14 static final int INCS_PER_THREAD = 10000000;
15 static final int NCPU = Runtime.getRuntime().availableProcessors();
16 static final ExecutorService pool = Executors.newCachedThreadPool();
17
18 static final class SynchronizedDoubleAdder {
19 double value;
20 synchronized double sum() { return value; }
21 synchronized void add(double x) { value += x; }
22 }
23
24 public static void main(String[] args) {
25 System.out.println("Warmup...");
26 int half = NCPU > 1 ? NCPU / 2 : 1;
27 syncTest(half, 1000);
28 adderTest(half, 1000);
29
30 for (int reps = 0; reps < 2; ++reps) {
31 System.out.println("Running...");
32 for (int i = 1; i <= NCPU * 2; i <<= 1) {
33 syncTest(i, INCS_PER_THREAD);
34 adderTest(i, INCS_PER_THREAD);
35 }
36 }
37 pool.shutdown();
38 }
39
40 static void syncTest(int nthreads, int incs) {
41 System.out.print("Synchronized ");
42 Phaser phaser = new Phaser(nthreads + 1);
43 SynchronizedDoubleAdder a = new SynchronizedDoubleAdder();
44 for (int i = 0; i < nthreads; ++i)
45 pool.execute(new SyncTask(a, phaser, incs));
46 report(nthreads, incs, timeTasks(phaser), a.sum());
47 }
48
49 static void adderTest(int nthreads, int incs) {
50 System.out.print("DoubleAdder ");
51 Phaser phaser = new Phaser(nthreads + 1);
52 DoubleAdder a = new DoubleAdder();
53 for (int i = 0; i < nthreads; ++i)
54 pool.execute(new AdderTask(a, phaser, incs));
55 report(nthreads, incs, timeTasks(phaser), a.sum());
56 }
57
58 static void report(int nthreads, int incs, long time, double sum) {
59 long total = (long)nthreads * incs;
60 if (sum != (double)total)
61 throw new Error(sum + " != " + total);
62 double secs = (double)time / (1000L * 1000 * 1000);
63 long rate = total * (1000L) / time;
64 System.out.printf("threads:%3d Time: %7.3fsec Incs per microsec: %4d\n",
65 nthreads, secs, rate);
66 }
67
68 static long timeTasks(Phaser phaser) {
69 phaser.arriveAndAwaitAdvance();
70 long start = System.nanoTime();
71 phaser.arriveAndAwaitAdvance();
72 phaser.arriveAndAwaitAdvance();
73 return System.nanoTime() - start;
74 }
75
76 static final class AdderTask implements Runnable {
77 final DoubleAdder adder;
78 final Phaser phaser;
79 final int incs;
80 volatile double result;
81 AdderTask(DoubleAdder adder, Phaser phaser, int incs) {
82 this.adder = adder;
83 this.phaser = phaser;
84 this.incs = incs;
85 }
86
87 public void run() {
88 phaser.arriveAndAwaitAdvance();
89 phaser.arriveAndAwaitAdvance();
90 DoubleAdder a = adder;
91 for (int i = 0; i < incs; ++i)
92 a.add(1.0);
93 result = a.sum();
94 phaser.arrive();
95 }
96 }
97
98 static final class SyncTask implements Runnable {
99 final SynchronizedDoubleAdder adder;
100 final Phaser phaser;
101 final int incs;
102 volatile double result;
103 SyncTask(SynchronizedDoubleAdder adder, Phaser phaser, int incs) {
104 this.adder = adder;
105 this.phaser = phaser;
106 this.incs = incs;
107 }
108
109 public void run() {
110 phaser.arriveAndAwaitAdvance();
111 phaser.arriveAndAwaitAdvance();
112 SynchronizedDoubleAdder a = adder;
113 for (int i = 0; i < incs; ++i)
114 a.add(1.0);
115 result = a.sum();
116 phaser.arrive();
117 }
118 }
119
120 }