-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.BufferedInputStream;
-import java.util.Vector;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Set;
+import java.io.*;
+import java.util.*;
public class Trace {
- int numThreads;
- int[] eventCounts;
- Event[][] eventstack;
- Hashtable<Integer, Counter> getcounter[];
- Hashtable<Integer, String> eventnames=new Hashtable<Integer, String>();
- public static final int STACKMAX=512;
+ // everything defined here should match coreprof.h
+ // definitions exactly
+ public static final int CP_EVENT_MASK = 3;
+ public static final int CP_EVENT_BASESHIFT = 8;
+
+ public static final int CP_EVENTTYPE_BEGIN = 1;
+ public static final int CP_EVENTTYPE_END = 2;
+ public static final int CP_EVENTTYPE_ONEOFF = 3;
+
+ public static final int CP_EVENTID_MAIN = 0x04;
+ public static final int CP_EVENTID_RUNMALLOC = 0x10;
+ public static final int CP_EVENTID_RUNFREE = 0x11;
+ public static final int CP_EVENTID_WORKSCHEDGRAB = 0x20;
+ public static final int CP_EVENTID_TASKDISPATCH = 0x30;
+ public static final int CP_EVENTID_TASKEXECUTE = 0x31;
+ public static final int CP_EVENTID_TASKRETIRE = 0x32;
+ public static final int CP_EVENTID_TASKSTALLVAR = 0x40;
+ public static final int CP_EVENTID_TASKSTALLMEM = 0x41;
void initNames() {
- eventnames.put(CP_MAIN, "MAIN ");
- eventnames.put(CP_RUNMALLOC,"RUNMALLOC");
- eventnames.put(CP_RUNFREE, "RUNFREE ");
+ eid2name = new Hashtable<Integer, String>();
+ eid2name.put( CP_EVENTID_MAIN, "MAIN " );
+ eid2name.put( CP_EVENTID_RUNMALLOC, "RUNMALLOC " );
+ eid2name.put( CP_EVENTID_RUNFREE, "RUNFREE " );
+ eid2name.put( CP_EVENTID_WORKSCHEDGRAB, "WORKSCHEDGRAB" );
+ eid2name.put( CP_EVENTID_TASKDISPATCH, "TASKDISPATCH " );
+ eid2name.put( CP_EVENTID_TASKEXECUTE, "TASKEXECUTE " );
+ eid2name.put( CP_EVENTID_TASKRETIRE, "TASKRETIRE " );
+ eid2name.put( CP_EVENTID_TASKSTALLVAR, "TASKSTALLVAR " );
+ eid2name.put( CP_EVENTID_TASKSTALLMEM, "TASKSTALLMEM " );
}
- public void printStats() {
- for(int i=0;i<numThreads;i++) {
- System.out.println("Thread "+i);
- for(Iterator<Integer> evit=getcounter[i].keySet().iterator();evit.hasNext();) {
- Integer event=evit.next();
- Counter c=getcounter[i].get(event);
- String eventname=eventnames.containsKey(event)?eventnames.get(event):Integer.toString(event);
- System.out.println("Event: "+eventname+" self time="+c.selftime+" total time="+c.totaltime+" count="+c.count);
- }
- System.out.println("-------------------------------------------------------------");
+ Hashtable<Integer, String> eid2name;
+
+
+
+ public static void main( String args[] ) {
+ if( args.length != 2 ) {
+ System.out.println( "usage: <coreprof.dat file> <trace out file>" );
+ System.exit( 0 );
+ }
+ Trace t = new Trace( args[0], args[1] );
+ }
+
+
+
+ // event IDs are a word, timestamps are long ints
+ public static final int WORD_SIZE = 4;
+ public static final int EVENT_SIZE = WORD_SIZE;
+ public static final int TIMESTAMP_SIZE = WORD_SIZE*2;
+
+ int numThreads;
+ ThreadData[] threadData;
+
+
+
+ public Trace( String inFile, String outFile ) {
+
+ openInputStreams( inFile );
+
+ initNames();
+
+ for( int i = 0; i < numThreads; i++ ) {
+ readThread( i );
}
+
+ printStats( outFile );
}
- public static int readInt(InputStream is) {
+
+ public static int readInt( InputStream is ) {
try {
- int b1=is.read();
- int b2=is.read();
- int b3=is.read();
- int b4=is.read();
- int retval=(b4<<24)|(b3<<16)|(b2<<8)|b1;
- if (retval<0)
+ int b1 = is.read();
+ int b2 = is.read();
+ int b3 = is.read();
+ int b4 = is.read();
+
+ int retval = (b4<<24)|(b3<<16)|(b2<<8)|b1;
+
+ if( retval < 0 ) {
throw new Error();
+ }
return retval;
- } catch (Exception e) {
+
+ } catch( Exception e ) {
throw new Error();
}
}
- public static long readLong(InputStream is) {
+
+ public static long readLong( InputStream is ) {
try {
- long b1=is.read();
- long b2=is.read();
- long b3=is.read();
- long b4=is.read();
- long b5=is.read();
- long b6=is.read();
- long b7=is.read();
- long b8=is.read();
- long retval=(b8<<56)|(b7<<48)|(b6<<40)|(b5<<32)|
- (b4<<24)|(b3<<16)|(b2<<8)|b1;
- if (retval<0)
- throw new Error();
- return retval;
- } catch (Exception e) {
+ long b1 = is.read();
+ long b2 = is.read();
+ long b3 = is.read();
+ long b4 = is.read();
+ long b5 = is.read();
+ long b6 = is.read();
+ long b7 = is.read();
+ long b8 = is.read();
+
+ long retval =
+ (b8<<56)|(b7<<48)|(b6<<40)|(b5<<32)|
+ (b4<<24)|(b3<<16)|(b2<< 8)|b1;
+
+ if( retval < 0 ) {
+ throw new Error();
+ }
+ return retval;
+
+ } catch( Exception e ) {
throw new Error();
}
}
- int readHeader(BufferedInputStream bir) {
- //First check version
- int offset=4;
- int version=readInt(bir);
- if (version!=0)
- throw new Error("Unsupported Version");
- //Second read number of threads
- offset+=4;
- numThreads=readInt(bir);
+ protected void openInputStreams( String filename ) {
- //Third read event counts for each Thread
- eventCounts=new int[numThreads];
- eventstack=new Event[numThreads][STACKMAX];
- for(int i=0;i<numThreads;i++) {
- eventCounts[i]=readInt(bir);
- offset+=4;
- }
- return offset;
- }
+ BufferedInputStream bis = null;
+ int offset = 0;
- BufferedInputStream threads[];
-
- public Trace(String filename) {
- initNames();
- BufferedInputStream bir=null;
- int offset=0;
try {
- bir=new BufferedInputStream(new FileInputStream(filename));
- offset=readHeader(bir);
- bir.close();
- } catch (Exception e) {
+ bis = new BufferedInputStream( new FileInputStream( filename ) );
+ offset = readHeader( bis );
+ bis.close();
+ } catch( Exception e ) {
e.printStackTrace();
- System.exit(-1);
+ System.exit( -1 );
}
- threads=new BufferedInputStream[numThreads];
- getcounter=new Hashtable[numThreads];
- for(int i=0;i<numThreads;i++) {
- getcounter[i]=new Hashtable<Integer,Counter>();
+ for( int i = 0; i < numThreads; ++i ) {
try {
- threads[i]=new BufferedInputStream(new FileInputStream(filename));
- int skip=offset;
- while (skip>0) {
- skip-=threads[i].skip(skip);
+ // point a thread's event stream to the
+ // beginning of its data within the input file
+ threadData[i].dataStream =
+ new BufferedInputStream( new FileInputStream( filename ) );
+
+ int skip = offset;
+ while( skip > 0 ) {
+ skip -= threadData[i].dataStream.skip( skip );
}
- offset+=4*eventCounts[i];
- } catch (Exception e) {
+
+ offset += WORD_SIZE*threadData[i].numDataWords;
+
+ } catch( Exception e ) {
e.printStackTrace();
- System.exit(-1);
+ System.exit( -1 );
}
}
}
- public void readThreads() {
- for(int i=0;i<numThreads;i++)
- readThread(i);
+
+ int readHeader( BufferedInputStream bis ) {
+
+ // check version
+ int version = readInt( bis );
+ if( version != 0 ) {
+ throw new Error( "Unsupported Version" );
+ }
+ int offset = WORD_SIZE;
+
+ // read number of threads
+ numThreads = readInt( bis );
+ offset += WORD_SIZE;
+
+ threadData = new ThreadData[numThreads];
+
+ // read number of words used for all events, per thread
+ for( int i = 0; i < numThreads; ++i ) {
+ threadData[i] = new ThreadData();
+ threadData[i].numDataWords = readInt( bis );
+ offset += WORD_SIZE;
+ }
+ return offset;
}
+
- public void readThread(int t) {
- BufferedInputStream bis=threads[t];
- int numevents=eventCounts[t];
- Event[] stack=eventstack[t];
- Hashtable<Integer, Counter> countertab=getcounter[t];
- int i=0;
- int depth=0;
- long time=0;
- while(i<numevents) {
- int event=readInt(bis);
- time=readLong(bis);
- int baseevent=event>>CP_BASE_SHIFT;
- i+=3; //time and event
-
- switch(event&CP_MASK) {
- case CP_BEGIN:
- enqueue(stack, depth, baseevent, time, countertab);
- depth++;
- break;
- case CP_END: {
- depth--;
- Event e=stack[depth];
- long elapsedtime=time-e.time;
- Counter c=e.counter;
- c.totaltime+=elapsedtime;
- c.selftime+=elapsedtime;
- if(depth-1>0) {
- Counter cn=stack[depth-1].counter;
- cn.selftime-=elapsedtime;
- }
- break;
- }
- case CP_EVENT: {
- Counter counter=countertab.get(event);
- if (counter==null) {
- Counter c=new Counter();
- countertab.put(event, c);
- counter=c;
- }
- counter.count++;
- break;
+ public void readThread( int tNum ) {
+
+ System.out.print( "Reading thread "+tNum );
+
+ ThreadData tdata = threadData[tNum];
+ tdata.stackDepth = 0;
+ long timeStamp = 0;
+ int i = 0;
+ int numProgress = 10;
+
+ int progressChunk = tdata.numDataWords / numProgress;
+ int j;
+ boolean[] progress = new boolean[numProgress];
+ for( j = 0; j < numProgress; ++j ) {
+ progress[j] = false;
+ }
+ j = 0;
+
+ while( i < tdata.numDataWords ) {
+
+ if( !progress[j] && i > j*progressChunk ) {
+ System.out.print( "." );
+ progress[j] = true;
+ if( j < numProgress - 1 ) {
+ ++j;
+ }
}
+
+ int eventRaw = readInt ( tdata.dataStream );
+ timeStamp = readLong( tdata.dataStream );
+ i += 3;
+
+ int eventType = eventRaw & CP_EVENT_MASK;
+ int eventID = eventRaw >> CP_EVENT_BASESHIFT;
+
+ switch( eventType ) {
+
+ case CP_EVENTTYPE_BEGIN: {
+ pushEvent( tdata, eventID, timeStamp );
+ } break;
+
+ case CP_EVENTTYPE_END: {
+ popEvent( tdata, eventID, timeStamp );
+ } break;
+
}
}
- if (depth!=0) {
- //get rid of last item also
- depth--;
- Event e=stack[depth];
- long elapsedtime=time-e.time;
- Counter c=e.counter;
- c.totaltime+=elapsedtime;
- c.selftime+=elapsedtime;
- if(depth-1>0) {
- Counter cn=stack[depth-1].counter;
- cn.selftime-=elapsedtime;
- }
+
+ System.out.println( "" );
+
+ while( tdata.stackDepth > 0 ) {
+ // worker threads currently do not exit gracefully, and therefore
+ // may not register END events, so supply them with whatever the
+ // latest known timestamp is
+ EventSummary eventSummary = tdata.eventStack.get( tdata.stackDepth );
+ popEvent( tdata, eventSummary.eventID, timeStamp );
+
+ --tdata.stackDepth;
}
}
- public static void enqueue(Event[] stack, int depth, int event, long time, Hashtable<Integer, Counter> getcounter) {
- Counter counter=getcounter.get(event);
- if (counter==null) {
- Counter c=new Counter();
- getcounter.put(event, c);
- counter=c;
- }
- counter.count++;
- if (stack[depth]==null) {
- stack[depth]=new Event(time,event);
- stack[depth].counter=counter;
+
+ protected void pushEvent( ThreadData tdata,
+ int eventID,
+ long timeStamp ) {
+
+ EventSummary eventSummary = null;
+
+ if( tdata.stackDepth == 0 ) {
+ // there are no parents, so look in the rootEvents
+ // for an existing EventSummary of this type
+ for( Iterator<EventSummary> itr = tdata.rootEvents.iterator();
+ itr.hasNext();
+ ) {
+ EventSummary es = itr.next();
+ if( es.eventID == eventID ) {
+ eventSummary = es;
+ break;
+ }
+ }
+ if( eventSummary == null ) {
+ // there is no summary for this event type yet,
+ // so add it
+ eventSummary = new EventSummary( eventID );
+ tdata.rootEvents.add( eventSummary );
+ }
+
} else {
- stack[depth].time=time;
- stack[depth].event=event;
- stack[depth].counter=counter;
+ // look through the parent's children for an existing
+ // EventSummary of this type
+ EventSummary esParent = tdata.eventStack.get( tdata.stackDepth - 1 );
+ for( Iterator<EventSummary> itr = esParent.children.iterator();
+ itr.hasNext();
+ ) {
+ EventSummary es = itr.next();
+ if( es.eventID == eventID ) {
+ eventSummary = es;
+ break;
+ }
+ }
+ if( eventSummary == null ) {
+ // there is no summary for this event type yet,
+ // under this parent, so add it
+ eventSummary = new EventSummary( eventID );
+ esParent.children.add( eventSummary );
+ eventSummary.parent = esParent;
+ }
+ }
+
+ eventSummary.timeStampBeginLatestInstance = timeStamp;
+
+ eventSummary.instanceCount++;
+
+ if( tdata.eventStack.size() <= tdata.stackDepth ) {
+ tdata.eventStack.setSize( 2*tdata.stackDepth + 20 );
+ }
+ tdata.eventStack.set( tdata.stackDepth, eventSummary );
+
+ tdata.stackDepth++;
+ }
+
+
+ protected void popEvent( ThreadData tdata,
+ int eventID,
+ long timeStamp ) {
+ tdata.stackDepth--;
+ if( tdata.stackDepth < 0 ) {
+ throw new Error( "Event stack underflow\n" );
+ }
+
+ EventSummary eventSummary = tdata.eventStack.get( tdata.stackDepth );
+ assert eventSummary != null;
+
+ if( eventSummary.eventID != eventID ) {
+ System.out.println( "Warning: event begin("+
+ getEventName( eventSummary.eventID )+
+ ") end("+
+ getEventName( eventID )+
+ ") mismatch!\n" );
+ }
+
+ long elapsedTime =
+ timeStamp - eventSummary.timeStampBeginLatestInstance;
+
+ eventSummary.totalTime_ticks += elapsedTime;
+ eventSummary.selfTime_ticks += elapsedTime;
+
+ if( tdata.stackDepth - 1 >= 0 ) {
+ EventSummary esParent = tdata.eventStack.get( tdata.stackDepth-1 );
+ esParent.selfTime_ticks -= elapsedTime;
}
}
- public static final int CP_BEGIN=0;
- public static final int CP_END=1;
- public static final int CP_EVENT=2;
- public static final int CP_MASK=3;
- public static final int CP_BASE_SHIFT=2;
-
- public static final int CP_MAIN=0;
- public static final int CP_RUNMALLOC=1;
- public static final int CP_RUNFREE=2;
- public static void main(String x[]) {
- Trace t=new Trace(x[0]);
- t.readThreads();
- t.printStats();
+
+
+ public void printStats( String filename ) {
+
+ System.out.println( "Printing..." );
+
+ try {
+ BufferedWriter bw =
+ new BufferedWriter( new FileWriter( filename ) );
+
+ for( int i = 0; i < numThreads; ++i ) {
+
+ ThreadData tdata = threadData[i];
+
+ bw.write( "----------------------------------\n" );
+ bw.write( "Thread "+i+"\n" );
+
+ for( Iterator<EventSummary> itr = tdata.rootEvents.iterator();
+ itr.hasNext();
+ ) {
+ EventSummary es = itr.next();
+ printEventSummary( bw, es, 0 );
+ }
+
+ bw.write( "\n" );
+ }
+
+ bw.close();
+
+ } catch( IOException e ) {}
+ }
+
+
+ public String getEventName( int eventID ) {
+ return
+ eid2name.containsKey( eventID ) ?
+ eid2name.get ( eventID ) :
+ Integer.toString ( eventID );
+ }
+
+
+ public void printEventSummary( BufferedWriter bw,
+ EventSummary es,
+ int depth )
+ throws IOException {
+
+ String strIndent = "";
+ for( int i = 0; i < depth; ++i ) {
+ strIndent += "--";
+ }
+
+ String strEventName = getEventName( es.eventID );
+
+ float tOfParent_perc;
+ String strPercParent = "";
+ if( es.parent != null ) {
+ float divisor = new Long( es.parent.totalTime_ticks ).floatValue();
+ if( divisor <= 0.00001f ) {
+ divisor = 0.00001f;
+ }
+
+ tOfParent_perc =
+ 100.0f *
+ new Long( es.totalTime_ticks ).floatValue() /
+ divisor;
+
+ strPercParent = String.format( " %%ofParent=%5.1f",
+ tOfParent_perc );
+ }
+
+ float tSelf_perc =
+ 100.0f *
+ new Long( es.selfTime_ticks ).floatValue() /
+ new Long( es.totalTime_ticks ).floatValue();
+
+ String strSelfStats =
+ String.format( " total(ticks)=%12dK, %%self=%5.1f, count=%d",
+ es.totalTime_ticks/1000,
+ tSelf_perc,
+ es.instanceCount );
+
+ bw.write( strIndent+
+ strEventName+
+ strPercParent+
+ strSelfStats+
+ "\n" );
+
+ for( Iterator<EventSummary> itr = es.children.iterator();
+ itr.hasNext();
+ ) {
+ EventSummary esChild = itr.next();
+ printEventSummary( bw, esChild, depth + 1 );
+ }
}
}