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

Comparing jsr166/src/test/loops/TimeoutExchangerLoops.java (file contents):
Revision 1.1 by dl, Sun Aug 7 19:25:55 2005 UTC vs.
Revision 1.2 by dl, Mon Feb 13 12:39:23 2006 UTC

# Line 10 | Line 10 | import java.util.concurrent.atomic.*;
10   import java.util.concurrent.locks.*;
11  
12   public class TimeoutExchangerLoops {
13 <    static final int  DEFAULT_THREADS        = 32;
14 <    static final long DEFAULT_TRIAL_MILLIS   = 5000;
13 >    static final int NCPUS = Runtime.getRuntime().availableProcessors();
14 >
15 >    static final int  DEFAULT_THREADS = NCPUS + 2;
16      static final long DEFAULT_PATIENCE_NANOS = 500000;
17 +    static final long DEFAULT_TRIAL_MILLIS   = 10000;
18  
17    static final ExecutorService pool = Executors.newCachedThreadPool();
18    
19      public static void main(String[] args) throws Exception {
20          int maxThreads = DEFAULT_THREADS;
21          long trialMillis = DEFAULT_TRIAL_MILLIS;
22          long patienceNanos = DEFAULT_PATIENCE_NANOS;
23 +        int nReps = 3;
24  
25          // Parse and check args
26          int argc = 0;
27 <        try {
28 <            while (argc < args.length) {
29 <                String option = args[argc++];
30 <                if (option.equals("-t"))
31 <                    trialMillis = Integer.parseInt(args[argc]);
32 <                else if (option.equals("-p"))
33 <                    patienceNanos = Long.parseLong(args[argc]);
34 <                else
35 <                    maxThreads = Integer.parseInt(option);
36 <                argc++;
37 <            }
37 <        }
38 <        catch (Exception e) {
39 <            e.printStackTrace();
40 <            System.exit(0);
27 >        while (argc < args.length) {
28 >            String option = args[argc++];
29 >            if (option.equals("-t"))
30 >                trialMillis = Integer.parseInt(args[argc]);
31 >            else if (option.equals("-p"))
32 >                patienceNanos = Long.parseLong(args[argc]);
33 >            else if (option.equals("-r"))
34 >                nReps = Integer.parseInt(args[argc]);
35 >            else
36 >                maxThreads = Integer.parseInt(option);
37 >            argc++;
38          }
39  
40          // Display runtime parameters
41          System.out.print("TimeoutExchangerTest");
42          System.out.print(" -t " + trialMillis);
43          System.out.print(" -p " + patienceNanos);
44 +        System.out.print(" -r " + nReps);
45          System.out.print(" max threads " + maxThreads);
46          System.out.println();
47  
48 <        // warmup
49 <        System.out.print("Threads: " + 2 + "\t");
50 <        oneRun(2, trialMillis, patienceNanos);
51 <        Thread.sleep(100);
52 <
53 <        int k = 4;
54 <        for (int i = 2; i <= maxThreads;) {
55 <            System.out.print("Threads: " + i + "\t");
56 <            oneRun(i, trialMillis, patienceNanos);
57 <            Thread.sleep(100);
58 <            if (i == k) {
59 <                k = i << 1;
60 <                i = i + (i >>> 1);
61 <            }
62 <            else
63 <                i = k;
48 >        System.out.println("Warmups..");
49 >        long warmupTime = 1000;
50 >        long sleepTime = 500;
51 >        if (false) {
52 >            for (int k = 0; k < 10; ++k) {
53 >                for (int j = 0; j < 10; ++j) {
54 >                    oneRun(2, (j + 1) * 1000, patienceNanos);
55 >                    Thread.sleep(sleepTime);
56 >                }
57 >            }
58 >        }
59 >
60 >        oneRun(3, warmupTime, patienceNanos);
61 >        Thread.sleep(sleepTime);
62 >
63 >        for (int i = maxThreads; i >= 2; i -= 1) {
64 >            oneRun(i, warmupTime, patienceNanos);
65 >            Thread.sleep(sleepTime);
66 >        }
67 >
68 >        for (int j = 0; j < nReps; ++j) {
69 >            System.out.println("Replication " + j);
70 >            for (int i = 2; i <= maxThreads; i += 2) {
71 >                oneRun(i, trialMillis, patienceNanos);
72 >                Thread.sleep(sleepTime);
73 >            }
74          }
67        pool.shutdown();
75      }
76  
77      static void oneRun(int nThreads, long trialMillis, long patienceNanos)
78          throws Exception {
79 <        CyclicBarrier barrier = new CyclicBarrier(nThreads+1);
80 <        long stopTime = System.currentTimeMillis() + trialMillis;
81 <        Exchanger<MutableInt> x = new Exchanger<MutableInt>();
79 >        System.out.printf("%4d threads", nThreads);
80 >        System.out.printf("%9dms", trialMillis);
81 >        final CountDownLatch start = new CountDownLatch(1);
82 >        Exchanger x = new Exchanger();
83          Runner[] runners = new Runner[nThreads];
84 +        Thread[] threads = new Thread[nThreads];
85 +        for (int i = 0; i < nThreads; ++i) {
86 +            runners[i] = new Runner(x, patienceNanos, start);
87 +            threads[i] = new Thread(runners[i]);
88 +            threads[i].start();
89 +        }
90 +        long startTime = System.nanoTime();
91 +        start.countDown();
92 +        Thread.sleep(trialMillis);
93          for (int i = 0; i < nThreads; ++i)
94 <            runners[i] = new Runner(x, stopTime, patienceNanos, barrier);
94 >            threads[i].interrupt();
95 >        long elapsed = System.nanoTime() - startTime;
96          for (int i = 0; i < nThreads; ++i)
97 <            pool.execute(runners[i]);
98 <        barrier.await();
81 <        barrier.await();
82 <        long iters = 0;
97 >            threads[i].join();
98 >        int iters = 0;
99          long fails = 0;
84        long check = 0;
100          for (int i = 0; i < nThreads; ++i) {
101 <            iters += runners[i].iterations;
101 >            iters += runners[i].iters;
102              fails += runners[i].failures;
88            check += runners[i].mine.value;
103          }
104 <        if (check != iters)
105 <            throw new Error("bad checksum " + iters + "/" + check);
106 <        long rate = (iters * 1000) / trialMillis;
104 >        if (iters <= 0) iters = 1;
105 >        long rate = iters * 1000L * 1000L * 1000L / elapsed;
106 >        long npt = elapsed / iters;
107          double failRate = (fails * 100.0) / (double)iters;
108 <        System.out.print(LoopHelpers.rightJustify(rate) + " iterations/s ");
109 <        System.out.printf("%9.5f", failRate);
110 <        System.out.print("% timeouts");
108 >        System.out.printf("%9d it/s ", rate);
109 >        System.out.printf("%9d ns/it", npt);
110 >        System.out.printf("%9.5f%% fails", failRate);
111          System.out.println();
112 +        //        x.printStats();
113      }
114  
115 <    static final class MutableInt {
101 <        int value;
102 <    }
103 <      
115 >
116      static final class Runner implements Runnable {
117 <        final Exchanger<MutableInt> x;
118 <        volatile long iterations;
107 <        volatile long failures;
108 <        volatile MutableInt mine;
109 <        final long stopTime;
117 >        final Exchanger exchanger;
118 >        final CountDownLatch start;
119          final long patience;
120 <        final CyclicBarrier barrier;
121 <        Runner(Exchanger<MutableInt> x, long stopTime,
122 <               long patience, CyclicBarrier b) {
123 <            this.x = x;
115 <            this.stopTime = stopTime;
120 >        volatile int iters;
121 >        volatile int failures;
122 >        Runner(Exchanger x, long patience, CountDownLatch start) {
123 >            this.exchanger = x;
124              this.patience = patience;
125 <            this.barrier = b;
118 <            mine = new MutableInt();
125 >            this.start = start;
126          }
127  
128          public void run() {
129 +            int i = 0;
130              try {
131 <                barrier.await();
132 <                MutableInt m = mine;
133 <                int i = 0;
134 <                int fails = 0;
135 <                do {
131 >                Exchanger x = exchanger;
132 >                Object m = new Integer(17);
133 >                long p = patience;
134 >                start.await();
135 >                for (;;) {
136                      try {
137 +                        Object e = x.exchange(m, p, TimeUnit.NANOSECONDS);
138 +                        if (e == null || e == m)
139 +                            throw new Error();
140 +                        m = e;
141                          ++i;
130                        m.value++;
131                        m = x.exchange(m, patience, TimeUnit.NANOSECONDS);
142                      } catch (TimeoutException to) {
143 <                        if (System.currentTimeMillis() >= stopTime)
144 <                            break;
145 <                        else
146 <                            ++fails;
143 >                        if (Thread.interrupted()) {
144 >                            iters = i;
145 >                            return;
146 >                        }
147 >                        ++i;
148 >                        ++failures;
149                      }
150 <                } while ((i & 127) != 0 || // only check time periodically
151 <                         System.currentTimeMillis() < stopTime);
152 <                
141 <                mine = m;
142 <                iterations = i;
143 <                failures = fails;
144 <                barrier.await();
145 <            } catch(Exception e) {
146 <                e.printStackTrace();
147 <                return;
150 >                }
151 >            } catch (InterruptedException ie) {
152 >                iters = i;
153              }
154          }
155      }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines