ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/LockLoops.java
Revision: 1.15
Committed: Thu Jun 9 15:28:19 2016 UTC (7 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.14: +25 -1 lines
Log Message:
add ReentrantReadLockLoop

File Contents

# User Rev Content
1 dl 1.1 /*
2 dl 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 jsr166 1.7 * http://creativecommons.org/publicdomain/zero/1.0/
5 dl 1.2 */
6 jsr166 1.15
7 dl 1.2 /*
8 jsr166 1.15 * Simple benchmark comparing various locking techniques.
9 dl 1.1 */
10    
11 jsr166 1.9 import java.util.*;
12 dl 1.1 import java.util.concurrent.*;
13     import java.util.concurrent.locks.*;
14    
15     public final class LockLoops {
16     static final ExecutorService pool = Executors.newCachedThreadPool();
17     static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
18     static boolean print = false;
19     static boolean doBuiltin = true;
20     static boolean doReadWrite = true;
21     static boolean doSemaphore = true;
22 jsr166 1.12 static boolean doStampedLock = true;
23 jsr166 1.8 static boolean doFair = true;
24 dl 1.1
25     public static void main(String[] args) throws Exception {
26     int maxThreads = 100;
27     int iters = 1000000;
28     int replications = 1;
29    
30 jsr166 1.3 if (args.length > 0)
31 dl 1.1 maxThreads = Integer.parseInt(args[0]);
32    
33 jsr166 1.3 if (args.length > 1)
34 dl 1.1 iters = Integer.parseInt(args[1]);
35    
36 jsr166 1.3 if (args.length > 2)
37 dl 1.1 replications = Integer.parseInt(args[2]);
38    
39     rng.setSeed(3122688L);
40    
41     print = false;
42     System.out.println("Warmup...");
43     oneTest(3, 10000);
44     Thread.sleep(1000);
45     oneTest(2, 10000);
46     Thread.sleep(100);
47     oneTest(1, 100000);
48     Thread.sleep(100);
49     oneTest(1, 100000);
50     Thread.sleep(1000);
51     print = true;
52    
53     for (int i = 1; i <= maxThreads; ++i) {
54     for (int j = 0; j < replications; ++j) {
55     System.out.println("Threads:" + i);
56     oneTest(i, iters / i);
57     Thread.sleep(100);
58     }
59     }
60     pool.shutdown();
61     }
62    
63     static void oneTest(int nthreads, int iters) throws Exception {
64     int v = rng.next();
65    
66     if (print)
67     System.out.print("No shared vars ");
68     new NoLockLoop().test(v, nthreads, iters * 10);
69     Thread.sleep(10);
70    
71     if (print)
72     System.out.print("No Lock + volatile ");
73     new NoLockVolatileLoop().test(v, nthreads, iters);
74     Thread.sleep(10);
75    
76     if (doBuiltin) {
77     if (print)
78     System.out.print("builtin lock ");
79     new BuiltinLockLoop().test(v, nthreads, iters);
80     Thread.sleep(10);
81     }
82    
83     if (print)
84     System.out.print("ReentrantLock ");
85     new ReentrantLockLoop().test(v, nthreads, iters);
86     Thread.sleep(10);
87    
88     if (doReadWrite) {
89     if (print)
90     System.out.print("ReentrantWriteLock ");
91     new ReentrantWriteLockLoop().test(v, nthreads, iters);
92     Thread.sleep(10);
93    
94     if (print)
95 jsr166 1.15 System.out.print("ReentrantReadLock ");
96     new ReentrantReadLockLoop().test(v, nthreads, iters);
97     Thread.sleep(10);
98    
99     if (print)
100 dl 1.1 System.out.print("ReentrantReadWriteLock");
101     new ReentrantReadWriteLockLoop().test(v, nthreads, iters);
102     Thread.sleep(10);
103     }
104    
105     if (doSemaphore) {
106     if (print)
107     System.out.print("Semaphore ");
108     new SemaphoreLoop().test(v, nthreads, iters);
109     Thread.sleep(10);
110    
111     if (print)
112     System.out.print("FairSemaphore ");
113     new FairSemaphoreLoop().test(v, nthreads, iters);
114     Thread.sleep(10);
115     }
116    
117     if (doFair) {
118     if (print)
119     System.out.print("FairReentrantLock ");
120     new FairReentrantLockLoop().test(v, nthreads, iters);
121     Thread.sleep(10);
122    
123     if (doReadWrite) {
124     if (print)
125     System.out.print("FairRWriteLock ");
126     new FairReentrantWriteLockLoop().test(v, nthreads, iters);
127     Thread.sleep(10);
128    
129     if (print)
130     System.out.print("FairRReadWriteLock ");
131     new FairReentrantReadWriteLockLoop().test(v, nthreads, iters);
132     Thread.sleep(10);
133     }
134     }
135 jsr166 1.12
136     if (doStampedLock) {
137     if (print)
138     System.out.print("StampedLockWrite ");
139     new StampedLockWriteLoop().test(v, nthreads, iters);
140     Thread.sleep(10);
141    
142     if (print)
143     System.out.print("StampedLockRead ");
144     new StampedLockReadLoop().test(v, nthreads, iters);
145     Thread.sleep(10);
146 jsr166 1.13
147     if (print)
148 jsr166 1.14 System.out.print("StampedLockOptRead");
149     new StampedLockOptimisticReadLoop().test(v, nthreads, iters);
150     Thread.sleep(10);
151    
152     if (print)
153 jsr166 1.13 System.out.print("StampedLockReadWrite");
154 jsr166 1.14 new StampedLockReadWriteLoop().test(v, nthreads, iters);
155 jsr166 1.13 Thread.sleep(10);
156 jsr166 1.12 }
157 dl 1.1 }
158    
159 jsr166 1.6 abstract static class LockLoop implements Runnable {
160 dl 1.1 int v;
161     int iters;
162     volatile int result;
163     final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
164     CyclicBarrier barrier;
165    
166     final void test(int initialValue, int nthreads, int iters) throws Exception {
167     v = initialValue;
168     this.iters = iters;
169     barrier = new CyclicBarrier(nthreads+1, timer);
170 jsr166 1.3 for (int i = 0; i < nthreads; ++i)
171 dl 1.1 pool.execute(this);
172     barrier.await();
173     barrier.await();
174     long time = timer.getTime();
175     if (print) {
176     long tpi = time / (iters * nthreads);
177     System.out.print("\t" + LoopHelpers.rightJustify(tpi) + " ns per update");
178 jsr166 1.4 // double secs = (double) time / 1000000000.0;
179 dl 1.1 // System.out.print("\t " + secs + "s run time");
180     System.out.println();
181     }
182    
183     if (result == 0) // avoid overoptimization
184     System.out.println("useless result: " + result);
185     }
186     abstract int loop(int n);
187     public final void run() {
188     try {
189 jsr166 1.3 barrier.await();
190 dl 1.1 result += loop(iters);
191     barrier.await();
192     }
193 jsr166 1.3 catch (Exception ie) {
194     return;
195 dl 1.1 }
196     }
197    
198     }
199    
200     private static class BuiltinLockLoop extends LockLoop {
201     final int loop(int n) {
202     int sum = 0;
203     while (n-- > 0) {
204 jsr166 1.5 synchronized (this) {
205 dl 1.1 v = LoopHelpers.compute1(v);
206     }
207     sum += LoopHelpers.compute2(v);
208     }
209     return sum;
210     }
211     }
212    
213     private static class NoLockLoop extends LockLoop {
214     final int loop(int n) {
215     int sum = 0;
216     int y = v;
217     while (n-- > 0) {
218     y = LoopHelpers.compute1(y);
219     sum += LoopHelpers.compute2(y);
220     }
221     return sum;
222     }
223     }
224    
225     private static class NoLockVolatileLoop extends LockLoop {
226 jsr166 1.6 private volatile int vv;
227 dl 1.1 final int loop(int n) {
228     int sum = 0;
229     while (n-- > 0) {
230     int y = LoopHelpers.compute1(vv);
231     vv = y;
232     sum += LoopHelpers.compute2(y);
233     }
234     return sum;
235     }
236     }
237    
238     private static class ReentrantLockLoop extends LockLoop {
239 jsr166 1.6 private final ReentrantLock lock = new ReentrantLock();
240 dl 1.1 final int loop(int n) {
241     int sum = 0;
242     while (n-- > 0) {
243     lock.lock();
244     try {
245     v = LoopHelpers.compute1(v);
246     }
247     finally {
248     lock.unlock();
249     }
250     sum += LoopHelpers.compute2(v);
251     }
252     return sum;
253     }
254     }
255    
256     private static class FairReentrantLockLoop extends LockLoop {
257 jsr166 1.6 private final ReentrantLock lock = new ReentrantLock(true);
258 dl 1.1 final int loop(int n) {
259     int sum = 0;
260     while (n-- > 0) {
261     lock.lock();
262     try {
263     v = LoopHelpers.compute1(v);
264     }
265     finally {
266     lock.unlock();
267     }
268     sum += LoopHelpers.compute2(v);
269     }
270     return sum;
271     }
272     }
273    
274     private static class ReentrantWriteLockLoop extends LockLoop {
275 jsr166 1.6 private final Lock lock = new ReentrantReadWriteLock().writeLock();
276 dl 1.1 final int loop(int n) {
277     int sum = 0;
278     while (n-- > 0) {
279     lock.lock();
280     try {
281     v = LoopHelpers.compute1(v);
282     }
283     finally {
284     lock.unlock();
285     }
286     sum += LoopHelpers.compute2(v);
287     }
288     return sum;
289     }
290     }
291    
292 jsr166 1.15 private static class ReentrantReadLockLoop extends LockLoop {
293     private final Lock lock = new ReentrantReadWriteLock().readLock();
294     final int loop(int n) {
295     int sum = 0;
296     while (n-- > 0) {
297     lock.lock();
298     try {
299     v = LoopHelpers.compute1(v);
300     }
301     finally {
302     lock.unlock();
303     }
304     sum += LoopHelpers.compute2(v);
305     }
306     return sum;
307     }
308     }
309    
310 dl 1.1 private static class ReentrantReadWriteLockLoop extends LockLoop {
311 jsr166 1.6 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
312 dl 1.1 final int loop(int n) {
313     int sum = 0;
314     while (n-- > 0) {
315     int x;
316     lock.readLock().lock();
317     try {
318     x = LoopHelpers.compute1(v);
319     }
320     finally {
321     lock.readLock().unlock();
322     }
323     lock.writeLock().lock();
324     try {
325     v = x;
326     }
327     finally {
328     lock.writeLock().unlock();
329     }
330     sum += LoopHelpers.compute2(v);
331     }
332     return sum;
333     }
334     }
335    
336     private static class FairReentrantWriteLockLoop extends LockLoop {
337     final Lock lock = new ReentrantReadWriteLock(true).writeLock();
338     final int loop(int n) {
339     int sum = 0;
340     while (n-- > 0) {
341     lock.lock();
342     try {
343     v = LoopHelpers.compute1(v);
344     }
345     finally {
346     lock.unlock();
347     }
348     sum += LoopHelpers.compute2(v);
349     }
350     return sum;
351     }
352     }
353    
354     private static class SemaphoreLoop extends LockLoop {
355 jsr166 1.6 private final Semaphore sem = new Semaphore(1, false);
356 dl 1.1 final int loop(int n) {
357     int sum = 0;
358     try {
359     while (n-- > 0) {
360     sem.acquire();
361     try {
362     v = LoopHelpers.compute1(v);
363     }
364     finally {
365     sem.release();
366     }
367     sum += LoopHelpers.compute2(v);
368     }
369     }
370     catch (InterruptedException ie) {
371     return sum;
372     }
373     return sum;
374     }
375     }
376 jsr166 1.12
377 dl 1.1 private static class FairSemaphoreLoop extends LockLoop {
378 jsr166 1.6 private final Semaphore sem = new Semaphore(1, true);
379 dl 1.1 final int loop(int n) {
380     int sum = 0;
381     try {
382     while (n-- > 0) {
383     sem.acquire();
384     try {
385     v = LoopHelpers.compute1(v);
386     }
387     finally {
388     sem.release();
389     }
390     sum += LoopHelpers.compute2(v);
391     }
392     }
393     catch (InterruptedException ie) {
394     return sum;
395     }
396     return sum;
397     }
398     }
399    
400     private static class FairReentrantReadWriteLockLoop extends LockLoop {
401 jsr166 1.6 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
402 dl 1.1 final int loop(int n) {
403     int sum = 0;
404     while (n-- > 0) {
405     int x;
406     lock.readLock().lock();
407     try {
408     x = LoopHelpers.compute1(v);
409     }
410     finally {
411     lock.readLock().unlock();
412     }
413     lock.writeLock().lock();
414     try {
415     v = x;
416     }
417     finally {
418     lock.writeLock().unlock();
419     }
420     sum += LoopHelpers.compute2(v);
421     }
422     return sum;
423     }
424     }
425 jsr166 1.12
426     private static class StampedLockWriteLoop extends LockLoop {
427     private final StampedLock lock = new StampedLock();
428     final int loop(int n) {
429     int sum = 0;
430     while (n-- > 0) {
431     long stamp = lock.writeLock();
432     try {
433     v = LoopHelpers.compute1(v);
434     }
435     finally {
436     lock.unlockWrite(stamp);
437     }
438     sum += LoopHelpers.compute2(v);
439     }
440     return sum;
441     }
442     }
443    
444     private static class StampedLockReadLoop extends LockLoop {
445     private final StampedLock lock = new StampedLock();
446     final int loop(int n) {
447     int sum = 0;
448     while (n-- > 0) {
449     long stamp = lock.readLock();
450     try {
451     v = LoopHelpers.compute1(v);
452     }
453     finally {
454     lock.unlockRead(stamp);
455     }
456     sum += LoopHelpers.compute2(v);
457     }
458     return sum;
459     }
460     }
461 jsr166 1.13
462 jsr166 1.14 private static class StampedLockOptimisticReadLoop extends LockLoop {
463     private final StampedLock lock = new StampedLock();
464     final int loop(int n) {
465     int sum = 0;
466     while (n-- > 0) {
467     long stamp;
468     do {
469     stamp = lock.tryOptimisticRead();
470     v = LoopHelpers.compute1(v);
471     } while (!lock.validate(stamp));
472     sum += LoopHelpers.compute2(v);
473     }
474     return sum;
475     }
476     }
477    
478 jsr166 1.13 private static class StampedLockReadWriteLoop extends LockLoop {
479     private final StampedLock lock = new StampedLock();
480     final int loop(int n) {
481     int sum = 0;
482     while (n-- > 0) {
483     int x;
484     long stamp = lock.readLock();
485     try {
486     x = LoopHelpers.compute1(v);
487     }
488     finally {
489     lock.unlockRead(stamp);
490     }
491     stamp = lock.writeLock();
492     try {
493     v = x;
494     } finally {
495     lock.unlockWrite(stamp);
496     }
497     sum += LoopHelpers.compute2(v);
498     }
499     return sum;
500     }
501     }
502 dl 1.1 }