ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/ExchangeLoops.java
(Generate patch)

Comparing jsr166/src/test/loops/ExchangeLoops.java (file contents):
Revision 1.1 by dl, Mon May 2 19:19:38 2005 UTC vs.
Revision 1.6 by jsr166, Mon Nov 2 23:42:46 2009 UTC

# Line 1 | Line 1
1   /*
2 < * @test
3 < * @summary checks to make sure a pipeline of exchangers passes data.
4 < */
5 < /*
6 < * Written by Doug Lea with assistance from members of JCP JSR-166
7 < * Expert Group and released to the public domain. Use, modify, and
8 < * redistribute this code in any way without acknowledgement.
2 > * Written by Bill Scherer and Doug Lea with assistance from members
3 > * of JCP JSR-166 Expert Group and released to the public domain, as
4 > * explained at http://creativecommons.org/licenses/publicdomain
5   */
6  
7   import java.util.concurrent.*;
8 + import java.util.concurrent.atomic.*;
9 + import java.util.concurrent.locks.*;
10  
11   public class ExchangeLoops {
12 <    static final ExecutorService pool = Executors.newCachedThreadPool();
15 <    static boolean print = false;
12 >    static final int NCPUS = Runtime.getRuntime().availableProcessors();
13  
14 <    static class Int {
15 <        public int value;
19 <        Int(int i) { value = i; }
20 <    }
21 <    
14 >    static final int  DEFAULT_THREADS = NCPUS + 2;
15 >    static final long DEFAULT_TRIAL_MILLIS   = 10000;
16  
17      public static void main(String[] args) throws Exception {
18 <        int maxStages = 100;
19 <        int iters = 100000;
18 >        int maxThreads = DEFAULT_THREADS;
19 >        long trialMillis = DEFAULT_TRIAL_MILLIS;
20 >        int nReps = 3;
21 >
22 >        // Parse and check args
23 >        int argc = 0;
24 >        while (argc < args.length) {
25 >            String option = args[argc++];
26 >            if (option.equals("-t"))
27 >                trialMillis = Integer.parseInt(args[argc]);
28 >            else if (option.equals("-r"))
29 >                nReps = Integer.parseInt(args[argc]);
30 >            else
31 >                maxThreads = Integer.parseInt(option);
32 >            argc++;
33 >        }
34  
35 <        if (args.length > 0)
36 <            maxStages = Integer.parseInt(args[0]);
35 >        // Display runtime parameters
36 >        System.out.print("ExchangeTest");
37 >        System.out.print(" -t " + trialMillis);
38 >        System.out.print(" -r " + nReps);
39 >        System.out.print(" max threads " + maxThreads);
40 >        System.out.println();
41 >        long warmupTime = 2000;
42 >        long sleepTime = 100;
43 >        int nw = (maxThreads >= 3) ? 3 : 2;
44 >
45 >        System.out.println("Warmups..");
46 >        oneRun(3, warmupTime);
47 >        Thread.sleep(sleepTime);
48 >
49 >        for (int i = maxThreads; i >= 2; i -= 1) {
50 >            oneRun(i, warmupTime++);
51 >            //            System.gc();
52 >            Thread.sleep(sleepTime);
53 >        }
54  
55 <        print = false;
56 <        System.out.println("Warmup...");
57 <        oneRun(2, 100000);
33 <        print = true;
34 <
35 <        for (int i = 2; i <= maxStages; i += (i+1) >>> 1) {
36 <            System.out.print("Threads: " + i + "\t: ");
37 <            oneRun(i, iters);
38 <        }
39 <        pool.shutdown();
40 <   }
41 <
42 <    static class Stage implements Runnable {
43 <        final int iters;
44 <        final Exchanger<Int> left;
45 <        final Exchanger<Int> right;
46 <        final CyclicBarrier barrier;
47 <        volatile int result;
48 <        Stage (Exchanger<Int> left,
49 <               Exchanger<Int> right,
50 <               CyclicBarrier b, int iters) {
51 <            this.left = left;
52 <            this.right = right;
53 <            barrier = b;
54 <            this.iters = iters;
55 >        /*
56 >        for (int i = maxThreads; i >= 2; i -= 1) {
57 >            oneRun(i, warmupTime++);
58          }
59 +        */
60  
61 <        public void run() {
62 <            try {
63 <                barrier.await();
64 <                Int item = new Int(hashCode());
65 <                for (int i = 0; i < iters; ++i) {
66 <                    if (left != null) {
63 <                        item.value = LoopHelpers.compute1(item.value);
64 <                        Int other = left.exchange(item);
65 <                        if (other == item || other == null)
66 <                            throw new Error("Failed Exchange");
67 <                        item = other;
68 <
69 <                    }
70 <                    if (right != null) {
71 <                        item.value = LoopHelpers.compute2(item.value);
72 <                        Int other = right.exchange(item);
73 <                        if (other == item || other == null)
74 <                            throw new Error("Failed Exchange");
75 <                        item = other;
76 <                    }
77 <                }
78 <                barrier.await();
79 <                
61 >        for (int j = 0; j < nReps; ++j) {
62 >            System.out.println("Trial: " + j);
63 >            for (int i = 2; i <= maxThreads; i += 2) {
64 >                oneRun(i, trialMillis);
65 >                //                System.gc();
66 >                Thread.sleep(sleepTime);
67              }
68 <            catch (Exception ie) {
69 <                ie.printStackTrace();
70 <                return;
68 >            for (int i = maxThreads; i >= 2; i -= 2) {
69 >                oneRun(i, trialMillis);
70 >                //                System.gc();
71 >                Thread.sleep(sleepTime);
72              }
73 +            Thread.sleep(sleepTime);
74          }
75 +
76 +
77      }
78  
79 <    static void oneRun(int nthreads, int iters) throws Exception {
80 <        LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
81 <        CyclicBarrier barrier = new CyclicBarrier(nthreads + 1, timer);
82 <        Exchanger<Int> l = null;
83 <        Exchanger<Int> r = new Exchanger<Int>();
84 <        for (int i = 0; i < nthreads; ++i) {
85 <            pool.execute(new Stage(l, r, barrier, iters));
86 <            l = r;
87 <            r = (i+2 < nthreads) ? new Exchanger<Int>() : null;
88 <        }
89 <        barrier.await();
90 <        barrier.await();
91 <        long time = timer.getTime();
92 <        if (print)
93 <            System.out.println(LoopHelpers.rightJustify(time / (iters * nthreads + iters * (nthreads-2))) + " ns per transfer");
79 >    static void oneRun(int nThreads, long trialMillis) throws Exception {
80 >        System.out.printf("%4d threads", nThreads);
81 >        Exchanger x = new Exchanger();
82 >        Runner[] runners = new Runner[nThreads];
83 >        Thread[] threads = new Thread[nThreads];
84 >        for (int i = 0; i < nThreads; ++i) {
85 >            runners[i] = new Runner(x);
86 >            threads[i] = new Thread(runners[i]);
87 >            //            int h = System.identityHashCode(threads[i]);
88 >            //            h ^= h << 1;
89 >            //            h ^= h >>> 3;
90 >            //            h ^= h << 10;
91 >            //            System.out.printf("%10x\n", h);
92 >        }
93 >
94 >        long startTime = System.nanoTime();
95 >        for (int i = 0; i < nThreads; ++i) {
96 >            threads[i].start();
97 >        }
98 >        Thread.sleep(trialMillis);
99 >        for (int i = 0; i < nThreads; ++i)
100 >            threads[i].interrupt();
101 >        long elapsed = System.nanoTime() - startTime;
102 >        for (int i = 0; i < nThreads; ++i)
103 >            threads[i].join();
104 >        int iters = 1;
105 >        //        System.out.println();
106 >        for (int i = 0; i < nThreads; ++i) {
107 >            int ipr = runners[i].iters;
108 >            //            System.out.println(ipr);
109 >            iters += ipr;
110 >        }
111 >        long rate = iters * 1000L * 1000L * 1000L / elapsed;
112 >        long npt = elapsed / iters;
113 >        System.out.printf("%9dms", elapsed / (1000L * 1000L));
114 >        System.out.printf("%9d it/s ", rate);
115 >        System.out.printf("%9d ns/it", npt);
116 >        System.out.println();
117 >        //        x.printStats();
118      }
119  
120 +    static final class Runner implements Runnable {
121 +        final Exchanger exchanger;
122 +        final Object mine = new Integer(2688);
123 +        volatile int iters;
124 +        Runner(Exchanger x) { this.exchanger = x; }
125 +
126 +        public void run() {
127 +            Exchanger x = exchanger;
128 +            Object m = mine;
129 +            int i = 0;
130 +            try {
131 +                for (;;) {
132 +                    Object e = x.exchange(m);
133 +                    if (e == null || e == m)
134 +                        throw new Error();
135 +                    m = e;
136 +                    ++i;
137 +                }
138 +            } catch (InterruptedException ie) {
139 +                iters = i;
140 +            }
141 +        }
142 +    }
143   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines