Subversion Repositories general

Compare Revisions

No changes between revisions

Ignore whitespace Rev 1129 → Rev 1130

/diskbench/trunk/build.xml
0,0 → 1,71
<project name="diskbench" default="compile" basedir=".">
 
<!--property name="build.compiler" value="jikes" /-->
 
<property name="src" location="src" />
<property name="conf" location="conf" />
<property name="classes" location="classes" />
<property name="lib" location="lib" />
 
<path id="classpath">
<fileset dir="${lib}">
<include name="*.jar" />
</fileset>
</path>
 
<path id="run.classpath">
<path refid="classpath" />
<pathelement path="${classes}" />
</path>
 
<target name="compile">
<mkdir dir="${classes}" />
 
<javac
srcdir="${src}"
destdir="${classes}"
classpathref="classpath"
debug="on"
nowarn="on"
/>
 
<copy file="${conf}/log4j.properties" todir="${classes}" />
</target>
 
<target name="clean">
<delete dir="${classes}"/>
<delete dir="${classes.deploy}"/>
</target>
 
<target name="run" depends="compile">
<java classname="ak.diskbench.DiskBench" fork="yes">
<classpath refid="run.classpath" />
<arg value="thr=10" />
<arg value="oneFile=false" />
<arg value="seed=0" />
<arg value="length=20971520" />
<arg value="buf=8192" />
<arg value="rwrite=1000" />
<arg value="rread=1000" />
<arg value="sleepMin=0" />
<arg value="sleepMax=0" />
</java>
</target>
 
<target name="fullrun" depends="compile">
<java classname="ak.diskbench.DiskBench" fork="yes">
<classpath refid="run.classpath" />
<arg value="thr=100" />
<arg value="req=100" />
<arg value="rpc=5" />
<arg value="sleepMin=1000" />
<arg value="sleepMax=10000" />
<arg value="timeout=60000" />
<arg value="firstUrl=" />
<arg value="http://tomcat.sun.int.26th.net/kickup/" />
</java>
</target>
 
<target name="all" depends="clean,compile" />
 
</project>
/diskbench/trunk/conf/log4j.properties
0,0 → 1,8
log4j.rootLogger=warn, stdout
 
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
 
log4j.logger.ak=info
 
/diskbench/trunk/lib/commons-logging.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/diskbench/trunk/lib/log4j.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/diskbench/trunk/src/ak/diskbench/DiskBench.java
0,0 → 1,570
// FIXME
// oneFile support
// better speed unit convert
//
package ak.diskbench;
 
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
 
import java.text.DecimalFormat;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
import java.io.File;
import java.io.RandomAccessFile;
import java.io.IOException;
 
public class DiskBench
{
private static Log log = LogFactory.getLog(DiskBench.class);
 
public static void main(String[] args)
throws Exception
{
DiskBench db = new DiskBench();
 
if(db.parseParams(args))
db.run();
}
 
// config
private int threadNumber = 1;
private boolean oneFile = false;
private long seed = 0;
private long length = 1024 * 1024; // 1M
private int bufLength = 8 * 1024; // 8K
private int randomWrites = 1000;
private int randomReads = 1000;
private int sleepMin = 0;
private int sleepMax = 0;
 
private int parseInt(String s, String prefix, String errorMsg)
throws Exception
{
try {
return Integer.parseInt(s.substring(prefix.length()));
}
catch(Exception ex) {
log.error(errorMsg);
throw ex;
}
}
 
private long parseLong(String s, String prefix, String errorMsg)
throws Exception
{
try {
return Long.parseLong(s.substring(prefix.length()));
}
catch(Exception ex) {
log.error(errorMsg);
throw ex;
}
}
 
private boolean parseParams(String[] args)
throws Exception
{
try {
for(int i = 0; i< args.length; i++) {
String s = args[i];
if(s.startsWith("thr=")) {
threadNumber = parseInt(s, "thr=",
"Cannot get number of threads from " + s);
}
else if(s.startsWith("oneFile=")) {
String s2 = s.substring("oneFile=".length());
if(s2.equals("true"))
oneFile = true;
else if(s2.equals("false"))
oneFile = false;
else {
log.error("Cannot get oneFile parameter from " + s);
throw new IllegalArgumentException("must be true or false");
}
}
else if(s.startsWith("seed=")) {
seed = parseLong(s, "seed=",
"Cannot get random seed from " + s);
}
else if(s.startsWith("length=")) {
length = parseLong(s, "length=",
"Cannot get length of file from " + s);
}
else if(s.startsWith("buf=")) {
bufLength = parseInt(s, "buf=",
"Cannot get length of buffer from " + s);
}
else if(s.startsWith("rwrite=")) {
randomWrites = parseInt(s, "rwrite=",
"Cannot get number of random writes from " + s);
}
else if(s.startsWith("rread=")) {
randomReads = parseInt(s, "rread=",
"Cannot get number of random reads from " + s);
}
else if(s.startsWith("sleepMin=")) {
sleepMin = parseInt(s, "sleepMin=",
"Cannot get min sleep from " + s);
}
else if(s.startsWith("sleepMax=")) {
sleepMax = parseInt(s, "sleepMax=",
"Cannot get max sleep from " + s);
}
else {
log.error("Unrecognized option " + s);
throw new IllegalArgumentException("unrecignized");
}
}
 
return true;
}
catch(Exception ex) {
return false;
}
}
 
private void run()
throws Exception
{
log.info("start " + threadNumber + "/" + oneFile + "/" + seed
+ " " + length + "/" + bufLength + " " + randomWrites + "/" + randomReads
+ " " + sleepMin + "/" + sleepMax);
 
List threads = new ArrayList();
List workers = new ArrayList();
 
DiskThread.prepare(threadNumber);
for(int i = 0; i < threadNumber; i++) {
log.debug("create thread " + i);
DiskThread dt = new DiskThread();
workers.add(dt);
 
dt.setFileName("file" + dt.getId() + ".txt");
dt.setSeed(seed);
dt.setCreateFile(!oneFile);
dt.setLength(length);
dt.setBufLength(bufLength);
dt.setRandomWrites(randomWrites);
dt.setRandomReads(randomReads);
dt.setSleepMin(sleepMin);
dt.setSleepMax(sleepMax);
 
Thread t = new Thread(dt);
threads.add(t);
t.start();
}
 
// wait for all
for(int i = 0; i < threads.size(); i++) {
log.debug("wait for thread " + i);
 
Thread t = (Thread)threads.get(i);
try {
t.join();
}
catch(InterruptedException ex) {
}
}
 
// statistics
int successes = 0;
int fails = 0;
long sequentialWriteStart = Long.MAX_VALUE;
long sequentialWriteStop = 0;
long sequentialReadStart = Long.MAX_VALUE;
long sequentialReadStop = 0;
long randomWriteStart = Long.MAX_VALUE;
long randomWriteStop = 0;
long randomReadStart = Long.MAX_VALUE;
long randomReadStop = 0;
for(int i = 0; i < workers.size(); i++) {
DiskThread dt = (DiskThread)workers.get(i);
ResultInfo r = dt.getResult();
if(r.success) {
successes++;
if(sequentialWriteStart > r.sequentialWriteStart)
sequentialWriteStart = r.sequentialWriteStart;
if(sequentialWriteStop < r.sequentialWriteStop)
sequentialWriteStop = r.sequentialWriteStop;
if(sequentialReadStart > r.sequentialReadStart)
sequentialReadStart = r.sequentialReadStart;
if(sequentialReadStop < r.sequentialReadStop)
sequentialReadStop = r.sequentialReadStop;
if(randomWriteStart > r.randomWriteStart)
randomWriteStart = r.randomWriteStart;
if(randomWriteStop < r.randomWriteStop)
randomWriteStop = r.randomWriteStop;
if(randomReadStart > r.randomReadStart)
randomReadStart = r.randomReadStart;
if(randomReadStop < r.randomReadStop)
randomReadStop = r.randomReadStop;
}
else {
fails++;
}
}
 
log.info("done "
+ "sequential write: " + (sequentialWriteStop - sequentialWriteStart) + "ms = "
+ Utils.calcSpeed(length * successes, sequentialWriteStop - sequentialWriteStart)
+ "; sequential read: " + (sequentialReadStop - sequentialReadStart) + "ms = "
+ Utils.calcSpeed(length * successes, sequentialReadStop - sequentialReadStart)
+ "; random write: " + (randomWriteStop - randomWriteStart) + "ms = "
+ Utils.calcSpeed(bufLength * randomWrites * successes,
randomWriteStop - randomWriteStart)
+ "; random read: " + (randomReadStop - randomReadStart) + "ms = "
+ Utils.calcSpeed(bufLength * randomReads * successes,
randomReadStop - randomReadStart)
+ "; " + fails + " failed");
}
}
 
class ResultInfo
{
public boolean success = false;
public long startTime;
public long stopTime;
public Exception exception;
public long sequentialWriteStart;
public long sequentialWriteStop;
public long sequentialReadStart;
public long sequentialReadStop;
public long randomWriteStart;
public long randomWriteStop;
public long randomReadStart;
public long randomReadStop;
public long writeSleep;
public long readSleep;
}
 
class DiskThread implements Runnable
{
private static int threadCount = 0;
private static Log log = LogFactory.getLog(DiskThread.class);
private static CyclicBarrier barrier;
 
public static void prepare(int threadNumber)
{
barrier = new CyclicBarrier(threadNumber);
}
 
private int id;
private String fileName;
private long seed = 0;
private boolean createFile = true;
private long length = 1024 * 1024; // 1M
private int bufLength = 8 * 1024; // 8K
private int randomWrites;
private int randomReads;
private int sleepMin = 0;
private int sleepMax = 0;
 
private ResultInfo result = new ResultInfo();
 
public DiskThread()
{
id = threadCount++;
}
 
public int getId()
{
return id;
}
 
public String getFileName()
{
return fileName;
}
 
public void setFileName(String fileName)
{
this.fileName = fileName;
}
 
public boolean getCreateFile()
{
return createFile;
}
 
public void setCreateFile(boolean createFile)
{
this.createFile = createFile;
}
 
public long getSeed()
{
return seed;
}
 
public void setSeed(long seed)
{
this.seed = seed;
}
 
public long getLength()
{
return length;
}
 
public void setLength(long length)
{
this.length = length;
}
 
public int getBufLength()
{
return bufLength;
}
 
public void setBufLength(int bufLength)
{
this.bufLength = bufLength;
}
 
public int getRandomWrites()
{
return randomWrites;
}
 
public void setRandomWrites(int randomWrites)
{
this.randomWrites = randomWrites;
}
 
public int getRandomReads()
{
return randomReads;
}
 
public void setRandomReads(int randomReads)
{
this.randomReads = randomReads;
}
 
public int getSleepMin()
{
return sleepMin;
}
 
public void setSleepMin(int sleepMin)
{
this.sleepMin = sleepMin;
}
 
public int getSleepMax()
{
return sleepMax;
}
 
public void setSleepMax(int sleepMax)
{
this.sleepMax = sleepMax;
}
 
public ResultInfo getResult()
{
return result;
}
 
private long sleep()
throws InterruptedException
{
if(sleepMax <= 0) return 0;
 
long sleep = (long)(Math.random() * (sleepMax - sleepMin)) + sleepMin;
log.trace(Integer.toString(id) + ": sleep for " + sleep + "ms");
Thread.sleep(sleep);
 
return sleep;
}
 
public void run()
{
log.debug(Integer.toString(id) + ": start");
result.startTime = System.currentTimeMillis();
result.writeSleep = 0;
result.readSleep = 0;
 
// try to delete the test file if it exists and abort execution on exception
if(createFile) {
try {
if((new File(fileName)).delete())
log.debug(Integer.toString(id) + ": test file "
+ fileName + " deleted");
}
catch(Exception ex) {
result.success = false;
result.stopTime = System.currentTimeMillis();
result.exception = ex;
log.warn(Integer.toString(id)
+ ": cannot delete the test file, execution aborted", ex);
return;
}
}
 
try {
RandomAccessFile file = new RandomAccessFile(fileName, "rw");
Random random = (seed > 0) ? new Random(seed) : new Random();
byte[] buf = new byte[bufLength];
 
random.nextBytes(buf);
 
// sequential write
if(createFile) {
result.sequentialWriteStart = System.currentTimeMillis();
for(int j = 0; j < length / bufLength; j++) {
file.write(buf);
}
result.sequentialWriteStop = System.currentTimeMillis();
log.info("sequential write: "
+ (result.sequentialWriteStop - result.sequentialWriteStart) + "ms = "
+ Utils.calcSpeed(length,
result.sequentialWriteStop - result.sequentialWriteStart));
barrier.await();
}
 
// sequential read
file.seek(0);
result.sequentialReadStart = System.currentTimeMillis();
while(file.read(buf) > 0);
result.sequentialReadStop = System.currentTimeMillis();
log.info("sequential read: "
+ (result.sequentialReadStop - result.sequentialReadStart) + "ms = "
+ Utils.calcSpeed(length,
result.sequentialReadStop - result.sequentialReadStart));
barrier.await();
 
// random write
result.randomWriteStart = System.currentTimeMillis();
for(int j = 0; j < randomWrites; j++) {
result.writeSleep += sleep();
file.seek((long)(random.nextDouble() * (length - bufLength)));
file.write(buf);
}
result.randomWriteStop = System.currentTimeMillis();
log.info("random write: " + (result.randomWriteStop - result.randomWriteStart) + "ms = "
+ Utils.calcSpeed(bufLength * randomWrites,
result.randomWriteStop - result.randomWriteStart));
barrier.await();
 
// random read
result.randomReadStart = System.currentTimeMillis();
for(int j = 0; j < randomReads; j++) {
result.readSleep += sleep();
file.seek((long)(random.nextDouble() * length));
file.read(buf);
}
result.randomReadStop = System.currentTimeMillis();
log.info("random read: " + (result.randomReadStop - result.randomReadStart) + "ms = "
+ Utils.calcSpeed(bufLength * randomReads,
result.randomReadStop - result.randomReadStart));
 
result.success = true;
result.stopTime = System.currentTimeMillis();
}
catch(Exception ex) {
result.success = false;
result.stopTime = System.currentTimeMillis();
result.exception = ex;
log.warn(Integer.toString(id), ex);
}
finally {
if(createFile) {
try {
(new File(fileName)).delete();
}
catch(Exception ex) {
log.warn(Integer.toString(id) + ": cannot delete the test file", ex);
}
}
}
 
log.debug(Integer.toString(id) + ": done" + (result.success ? "" : " with error"));
}
}
 
class Utils
{
private static final String[] units = {"", "K", "M", "G", "T"};
 
public static String calcSpeed(long amount, long time)
{
if(time == 0) return "-";
 
double speed = (double)amount / time * 1000;
int power = 0;
 
while(speed >= 10000 && power < units.length) {
power++;
speed /= 1024;
}
 
return (new DecimalFormat("0.00")).format(speed) + units[power] + "B/s";
}
}
 
// replacement of java.util.concurrent.CyclicBarrier from Java 1.5
class CyclicBarrier
{
private int parties;
private int waiting = 0;
private Runnable barrierAction = null;
 
public CyclicBarrier(int parties)
{
this(parties, null);
}
 
public CyclicBarrier(int parties, Runnable barrierAction)
{
this.parties = parties;
this.barrierAction = barrierAction;
}
 
public int await()
throws InterruptedException
{
synchronized(this) {
int n = parties - waiting - 1;
 
waiting++;
if(waiting == parties) {
if(barrierAction != null)
barrierAction.run();
 
waiting = 0;
notifyAll();
}
else {
wait();
}
 
return n;
}
}
 
public void reset()
{
synchronized(this) {
waiting = 0;
notifyAll();
}
}
 
public int getNumberWaiting()
{
return waiting;
}
 
public int getParties()
{
return parties;
}
}
 
/diskbench/trunk
Property changes:
Added: svn:ignore
+classes
+