ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/ConcurrentQueueLoops.java
Revision: 1.1
Committed: Mon May 2 19:19:38 2005 UTC (19 years ago) by dl
Branch: MAIN
Log Message:
Put misc performance tests into CVS

File Contents

# Content
1 /*
2 * @test %I% %E%
3 * @bug 4486658
4 * @compile -source 1.5 ConcurrentQueueLoops.java
5 * @run main/timeout=230 ConcurrentQueueLoops
6 * @summary Checks that a set of threads can repeatedly get and modify items
7 */
8 /*
9 * Written by Doug Lea with assistance from members of JCP JSR-166
10 * Expert Group and released to the public domain. Use, modify, and
11 * redistribute this code in any way without acknowledgement.
12 */
13
14 import java.util.*;
15 import java.util.concurrent.*;
16 import java.util.concurrent.atomic.*;
17
18 public class ConcurrentQueueLoops {
19 static final ExecutorService pool = Executors.newCachedThreadPool();
20 static AtomicInteger totalItems;
21 static boolean print = false;
22
23 public static void main(String[] args) throws Exception {
24 int maxStages = 8;
25 int items = 100000;
26
27 Class klass = null;
28 if (args.length > 0) {
29 try {
30 klass = Class.forName(args[0]);
31 } catch(ClassNotFoundException e) {
32 throw new RuntimeException("Class " + args[0] + " not found.");
33 }
34 }
35 else
36 klass = java.util.concurrent.ConcurrentLinkedQueue.class;
37
38 if (args.length > 1)
39 maxStages = Integer.parseInt(args[1]);
40
41 System.out.print("Class: " + klass.getName());
42 System.out.println(" stages: " + maxStages);
43
44 print = false;
45 System.out.println("Warmup...");
46 oneRun(klass, 1, items);
47 Thread.sleep(100);
48 oneRun(klass, 1, items);
49 Thread.sleep(100);
50 print = true;
51
52 for (int i = 1; i <= maxStages; i += (i+1) >>> 1) {
53 oneRun(klass, i, items);
54 }
55 pool.shutdown();
56 }
57
58 static class Stage implements Callable<Integer> {
59 final Queue<Integer> queue;
60 final CyclicBarrier barrier;
61 int items;
62 Stage (Queue<Integer> q, CyclicBarrier b, int items) {
63 queue = q;
64 barrier = b;
65 this.items = items;
66 }
67
68 public Integer call() {
69 // Repeatedly take something from queue if possible,
70 // transform it, and put back in.
71 try {
72 barrier.await();
73 int l = (int)System.nanoTime();
74 int takes = 0;
75 int seq = l;
76 for (;;) {
77 Integer item = queue.poll();
78 if (item != null) {
79 ++takes;
80 l = LoopHelpers.compute2(item.intValue());
81 }
82 else if (takes != 0) {
83 totalItems.getAndAdd(-takes);
84 takes = 0;
85 }
86 else if (totalItems.get() <= 0)
87 break;
88 l = LoopHelpers.compute1(l);
89 if (items > 0) {
90 --items;
91 while (!queue.offer(new Integer(l^seq++))) ;
92 }
93 else if ( (l & (3 << 5)) == 0) // spinwait
94 Thread.sleep(1);
95 }
96 return new Integer(l);
97 }
98 catch (Exception ie) {
99 ie.printStackTrace();
100 throw new Error("Call loop failed");
101 }
102 }
103 }
104
105 static void oneRun(Class klass, int n, int items) throws Exception {
106 Queue<Integer> q = (Queue<Integer>)klass.newInstance();
107 LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
108 CyclicBarrier barrier = new CyclicBarrier(n + 1, timer);
109 totalItems = new AtomicInteger(n * items);
110 ArrayList<Future<Integer>> results = new ArrayList<Future<Integer>>(n);
111 for (int i = 0; i < n; ++i)
112 results.add(pool.submit(new Stage(q, barrier, items)));
113
114 if (print)
115 System.out.print("Threads: " + n + "\t:");
116 barrier.await();
117 int total = 0;
118 for (int i = 0; i < n; ++i) {
119 Future<Integer> f = results.get(i);
120 Integer r = f.get();
121 total += r.intValue();
122 }
123 long endTime = System.nanoTime();
124 long time = endTime - timer.startTime;
125 if (print)
126 System.out.println(LoopHelpers.rightJustify(time / (items * n)) + " ns per item");
127 if (total == 0) // avoid overoptimization
128 System.out.println("useless result: " + total);
129
130 }
131 }