1 22 package org.jboss.test.perf.test; 23 import org.jboss.test.perf.interfaces.*; 24 25 import java.util.*; 26 27 public class Thrasher implements Runnable { 28 29 static final int ACTION_SINGLE_READ = 0; 30 static final int ACTION_SINGLE_WRITE = 1; 31 static final int ACTION_BLOCK_READ = 2; 32 static final int ACTION_BLOCK_WRITE = 3; 33 static final int ACTION_FAILURE = 4; 34 static final int ACTION_COUNT = 5; 35 36 static int[] timers = new int[ACTION_COUNT]; 37 static int[] counters = new int[ACTION_COUNT]; 38 39 static final String [] ACTION_LABELS = { 40 "single reads ", 41 "single writes", 42 "block reads ", 43 "block writes ", 44 "**FAILURES** ", 45 }; 46 47 static final int ARG_THREADS = 0; 48 static final int ARG_ITERATIONS = 1; 49 static final int ARG_READ_PERC = 2; 50 static final int ARG_BLOCK_PERC = 3; 51 static final int ARG_BLOCK_MIN = 4; 52 static final int ARG_BLOCK_MAX = 5; 53 static final int ARG_SLEEP_MIN = 6; 54 static final int ARG_SLEEP_MAX = 7; 55 static final int ARG_ID_MIN = 8; 56 static final int ARG_ID_MAX = 9; 57 static final int ARG_COUNT = 10; 58 59 static final String [] ARG_LABELS = { 60 "threads ", "How many threads to run", 61 "iterations", "How many iterations per thread", 62 "read_perc ", "What percentage of access is readonly", 63 "block_perc", "What percentage of access is block oriented", 64 "block_min ", "The minimum block size per access (inclusive)", 65 "block_max ", "The maximum block size per access (exclusive)", 66 "sleep_min ", "The minimum sleep period between accesses in ms (inclusive)", 67 "sleep_max ", "The maximum sleep period between accesses in ms (exclusive)", 68 "id_min ", "The minimum id accessed (inclusive)", 69 "id_max ", "The maximum id accessed (exclusive)", 70 }; 71 72 static final int[] argValues = new int[ARG_COUNT]; 73 74 static private void usage() { 75 System.out.println("Usage: java Thrasher <jndi-name> [-options]\n\n" + 76 " where options include:"); 77 for(int a = 0; a < ARG_COUNT; a++) { 78 System.out.println(" -" + ARG_LABELS[a * 2] + 79 " <n> \t" + ARG_LABELS[a * 2 + 1]); 80 } 81 System.exit(1); 82 } 83 84 public static void main(String [] args) throws Exception { 85 86 if(args.length < 1) { 87 usage(); 88 } 89 String jndiName = args[0]; 90 91 int[] argValues = new int[ARG_COUNT]; 92 argValues[ARG_THREADS] = 1; 93 argValues[ARG_ITERATIONS] = 20; 94 argValues[ARG_READ_PERC] = 90; 95 argValues[ARG_BLOCK_PERC] = 10; 96 argValues[ARG_BLOCK_MIN] = 2; 97 argValues[ARG_BLOCK_MAX] = 10; 98 argValues[ARG_SLEEP_MIN] = 0; 99 argValues[ARG_SLEEP_MAX] = 0; 100 argValues[ARG_ID_MIN] = 0; 101 argValues[ARG_ID_MAX] = 100; 102 103 for(int i = 1; i < args.length; i++) { 104 boolean found = false; 105 for(int a = 0; a < ARG_COUNT; a++) { 106 String argLabel = "-" + ARG_LABELS[a * 2].trim(); 107 if(args[i].equals(argLabel)) { 108 found = true; 109 if(++i >= args.length) { 110 System.out.println("Value expected for argument: " + argLabel); 111 System.exit(1); 112 } 113 int value; 114 try { 115 value = Integer.parseInt(args[i]); 116 } 117 catch(NumberFormatException e) { 118 System.out.println("Numeric value expected for argument: " + argLabel); 119 System.out.println(" error: " + e); 120 System.exit(1); 121 return; 122 } 123 argValues[a] = value; 124 break; 125 } 126 } 127 if(!found) { 128 usage(); 129 } 130 } 131 Thrasher[] thrashers = new Thrasher[argValues[ARG_THREADS]]; 132 { 133 Thread [] threads = new Thread [argValues[ARG_THREADS]]; 134 for(int i = 0; i < argValues[ARG_THREADS]; i++) { 135 thrashers[i] = new Thrasher(jndiName, argValues); 136 threads[i] = new Thread (thrashers[i], "Thrasher[" + i + "]"); 137 if(i < 5 || 138 i >= argValues[ARG_THREADS] - 5) { 139 System.out.println("Starting thread: " + threads[i]); 140 } 141 threads[i].start(); 142 } 143 for(int i = 0; i < argValues[ARG_THREADS]; i++) { 144 threads[i].join(); 145 } 146 } 147 System.out.println("Configuration:"); 148 for(int a = 0; a < ARG_COUNT; a++) { 149 System.out.println("\t" + ARG_LABELS[a * 2] + "\t" + argValues[a]); 150 } 151 { 152 System.out.println("Actions:"); 153 for(int i = 0; i < ACTION_COUNT; i++) { 154 if(counters[i] != 0) { 155 float avg = (float) timers[i] / counters[i]; 156 avg = (long) (avg * 10) / 10f; 158 System.out.println("\t" + counters[i] + "\t" + 159 ACTION_LABELS[i] + "\tavg:\t" + 160 avg + "\tms/Tx"); 161 } 162 } 163 } 164 System.out.println("Performance:"); 165 long totalTime = 0; 166 for(int i = 0; i < argValues[ARG_THREADS]; i++) { 167 long thrasherTime = thrashers[i]._elapsedTime; 168 totalTime += thrasherTime; 169 if(i < 5 || 170 i >= argValues[ARG_THREADS] - 5) { 171 float msPerTx = (float) thrasherTime / argValues[ARG_ITERATIONS]; 173 float txPerSec = 1000 / msPerTx; 174 msPerTx = (long) (msPerTx * 10) / 10f; 176 txPerSec = (long) (txPerSec * 1000) / 1000f; 177 System.out.println("\tThread[" + i + "]: \t" + 178 txPerSec + "\tTx/s \t" + 179 msPerTx + "\tms/Tx"); 180 } 181 } 182 { 183 float msPerTx = (float) totalTime / argValues[ARG_THREADS] / argValues[ARG_ITERATIONS]; 184 float txPerSec = 1000 / msPerTx; 185 msPerTx = (long) (msPerTx * 10) / 10f; 187 txPerSec = (long) (txPerSec * 1000) / 1000f; 188 System.out.println("\tAverage: \t" + 189 txPerSec + "\tTx/s \t" + 190 msPerTx + "\tms/Tx"); 191 float throughput = txPerSec * argValues[ARG_THREADS]; 192 throughput = (long) (throughput * 1000) / 1000f; 194 System.out.println("\tThroughput: \t" + throughput + "\tTx/s"); 195 } 196 } 197 198 private String _jndiName; 199 private int[] _args; 200 private long _elapsedTime; 201 202 private Thrasher(String jndiName, int[] args) { 203 _jndiName = jndiName; 204 _args = args; 205 } 206 207 public void run() { 208 try { 209 javax.naming.Context context = new javax.naming.InitialContext (); 210 Object ref = context.lookup("Session"); 211 SessionHome sessionHome = (SessionHome) ref; 212 217 Session session = sessionHome.create(_jndiName); 218 java.util.Random random = new java.util.Random (); 219 for(int i = 0; i < _args[ARG_ITERATIONS]; i++) { 220 boolean doBlocks = random.nextFloat() < _args[ARG_BLOCK_PERC] / 100f; 221 boolean doReadonly = random.nextFloat() < _args[ARG_READ_PERC] / 100f; 222 int id = getRandom(random, _args[ARG_ID_MIN], _args[ARG_ID_MAX]); 223 int blockSize = doBlocks ? getRandom(random, _args[ARG_BLOCK_MIN], _args[ARG_BLOCK_MAX]) : 0; 224 long before = System.currentTimeMillis(); 225 int action; 226 if(doBlocks) { 227 if(id + blockSize > _args[ARG_ID_MAX]) { 228 id = _args[ARG_ID_MAX] - blockSize; 230 } 231 if(doReadonly) { 232 session.read(id, id + blockSize); 233 action = ACTION_BLOCK_READ; 234 } 235 else { 236 session.write(id, id + blockSize); 237 action = ACTION_BLOCK_WRITE; 238 } 239 } 240 else { 241 if(doReadonly) { 242 session.read(id); 243 action = ACTION_SINGLE_READ; 244 } 245 else { 246 session.write(id); 247 action = ACTION_SINGLE_WRITE; 248 } 249 } 250 long after = System.currentTimeMillis(); 251 _elapsedTime += after - before; 252 timers[action] += after - before; 253 counters[action]++; 254 int sleep = getRandom(random, _args[ARG_SLEEP_MIN], _args[ARG_SLEEP_MAX]); 255 if(sleep != 0) { 256 try { 257 Thread.currentThread().sleep(sleep); 258 } 259 catch(InterruptedException e) { 260 } 262 } 263 } 264 session.remove(); 265 } 266 catch(Exception e) { 267 counters[ACTION_FAILURE]++; 268 e.printStackTrace(); 269 } 270 } 271 272 static int getRandom(java.util.Random random, int min, int max) { 273 int result = Math.abs(random.nextInt()); 275 int range = max - min; 277 if(range <= 0) { 278 return min; 279 } 280 result %= range; 281 result += min; 282 return result; 283 } 284 285 } 286 | Popular Tags |