package org.multiverse.stms.gamma.benchmarks; import org.benchy.BenchyUtils; import org.junit.Ignore; import org.junit.Test; import org.multiverse.MultiverseConstants; import org.multiverse.stms.gamma.GammaStm; import org.multiverse.stms.gamma.transactionalobjects.GammaTxnLong; import org.multiverse.utils.ToolUnsafe; import sun.misc.Unsafe; @Ignore public class BasicPerformanceDriver { public static void main(String[] args) { BasicPerformanceDriver driver = new BasicPerformanceDriver(); driver.casPerformance(); } @Test public void test() { GammaStm stm = new GammaStm(); GammaTxnLong ref = new GammaTxnLong(stm); final long transactionCount = 1000 * 1000 * 1000; final long startMs = System.currentTimeMillis(); for (long k = 0; k < transactionCount; k++) { ref.arriveAndLock(1, MultiverseConstants.LOCKMODE_EXCLUSIVE); //ref.orec = 0; ref.departAfterUpdateAndUnlock(); } long durationMs = System.currentTimeMillis() - startMs; String s = BenchyUtils.operationsPerSecondPerThreadAsString(transactionCount, durationMs, 1); System.out.printf("Performance is %s transactions/second/thread\n", s); } @Test public void casPerformance() { final long transactionCount = 1000 * 1000 * 1000; final long startMs = System.currentTimeMillis(); Cas cas = new Cas(); final long t = transactionCount / 10; for (long k = 0; k < t; k++) { cas.atomicInc(); cas.atomicInc(); cas.atomicInc(); cas.atomicInc(); cas.atomicInc(); cas.atomicInc(); cas.atomicInc(); cas.atomicInc(); cas.atomicInc(); cas.atomicInc(); } long durationMs = System.currentTimeMillis() - startMs; String s = BenchyUtils.operationsPerSecondPerThreadAsString(transactionCount, durationMs, 1); System.out.printf("Performance is %s transactions/second/thread\n", s); } @Test public void volatileWritePerformance() { final long transactionCount = 1000 * 1000 * 1000; final long startMs = System.currentTimeMillis(); final Cas cas = new Cas(); final long t = transactionCount / 10; for (long k = 0; k < t; k++) { cas.volatile_value++; cas.volatile_value++; cas.volatile_value++; cas.volatile_value++; cas.volatile_value++; cas.volatile_value++; cas.volatile_value++; cas.volatile_value++; cas.volatile_value++; cas.volatile_value++; } long durationMs = System.currentTimeMillis() - startMs; String s = BenchyUtils.operationsPerSecondPerThreadAsString(transactionCount, durationMs, 1); System.out.printf("Performance is %s transactions/second/thread\n", s); } @Test public void basicWritePerformance() { final long transactionCount = 1000 * 1000 * 1000; final long startMs = System.currentTimeMillis(); final Cas cas = new Cas(); for (long k = 0; k < transactionCount; k++) { cas.volatile_value++;//lock cas.volatile_value++;//version cas.volatile_value++;//value cas.volatile_value++;//unlock } long durationMs = System.currentTimeMillis() - startMs; String s = BenchyUtils.operationsPerSecondPerThreadAsString(transactionCount, durationMs, 1); System.out.printf("Performance is %s transactions/second/thread\n", s); } @Test public void basicWritePerformanceWithNonVolatileVersionAndValue() { final long transactionCount = 1000 * 1000 * 1000; final long startMs = System.currentTimeMillis(); final Cas cas = new Cas(); for (long k = 0; k < transactionCount; k++) { cas.volatile_value++;//lock cas.value++;//version cas.value++;//value cas.volatile_value++;//unlock } long durationMs = System.currentTimeMillis() - startMs; String s = BenchyUtils.operationsPerSecondPerThreadAsString(transactionCount, durationMs, 1); System.out.printf("Performance is %s transactions/second/thread\n", s); } class Cas { protected final Unsafe ___unsafe = ToolUnsafe.getUnsafe(); protected final long valueOffset; { try { valueOffset = ___unsafe.objectFieldOffset( Cas.class.getDeclaredField("volatile_value")); } catch (Exception ex) { throw new Error(ex); } } volatile long volatile_value; long value; void atomicInc() { final long oldValue = volatile_value; final long newValue = oldValue + 1; ___unsafe.compareAndSwapLong(this, valueOffset, oldValue, newValue); } } }