import java.util.Set;
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 = 2;
+
+ public static final int CP_EVENTTYPE_BEGIN = 0;
+ public static final int CP_EVENTTYPE_END = 1;
+ public static final int CP_EVENTTYPE_ONEOFF = 2;
+
+ public static final int CP_EVENTID_MAIN = 0;
+ public static final int CP_EVENTID_RUNMALLOC = 1;
+ public static final int CP_EVENTID_RUNFREE = 2;
+ public static final int CP_EVENTID_TASKDISPATCH = 3;
+ public static final int CP_EVENTID_TASKRETIRE = 4;
+ public static final int CP_EVENTID_TASKSTALLVAR = 5;
+ public static final int CP_EVENTID_TASKSTALLMEM = 6;
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_TASKDISPATCH, "TASKDISPATCH" );
+ 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("-------------------------------------------------------------");
+ public static void main( String args[] ) {
+ if( args.length != 1 ) {
+ System.out.println( "usage: <coreprof.dat file>" );
+ System.exit( 0 );
}
+ Trace t = new Trace( args[0] );
+ t.printStats();
}
- 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)
- throw new Error();
- return retval;
- } catch (Exception e) {
- throw new Error();
- }
- }
- 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) {
- throw new Error();
- }
- }
+ // 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;
+ public static final int STACKMAX = 512;
- 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);
-
- //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;
- }
+ int numThreads;
+ BufferedInputStream[] threadNum2stream;
+ int[] threadNum2numWords;
+ Event[][] threadNum2eventStack;
+ Hashtable<Integer, Counter>[] threadNum2eid2c;
+ Hashtable<Integer, String> eid2name;
- BufferedInputStream threads[];
- public Trace(String filename) {
+ public Trace( String filename ) {
+ openInputStreams( filename );
initNames();
- BufferedInputStream bir=null;
- int offset=0;
+ readThreads();
+ }
+
+
+ protected void openInputStreams( String filename ) {
+
+ BufferedInputStream bis = 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>();
+ threadNum2stream = new BufferedInputStream[numThreads];
+
+ 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
+ threadNum2stream[i] =
+ new BufferedInputStream( new FileInputStream( filename ) );
+
+ int skip = offset;
+ while( skip > 0 ) {
+ skip -= threadNum2stream[i].skip( skip );
}
- offset+=4*eventCounts[i];
- } catch (Exception e) {
+
+ offset += WORD_SIZE*threadNum2numWords[i];
+
+ } catch( Exception e ) {
e.printStackTrace();
- System.exit(-1);
+ System.exit( -1 );
}
}
}
+
+ 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;
+
+ // read number of words used for event, per thread
+ threadNum2numWords = new int[numThreads];
+ threadNum2eventStack = new Event[numThreads][STACKMAX];
+ for( int i = 0; i < numThreads; ++i ) {
+ threadNum2numWords[i] = readInt( bis );
+ offset += WORD_SIZE;
+ }
+ return offset;
+ }
+
+
public void readThreads() {
- for(int i=0;i<numThreads;i++)
- readThread(i);
+ // cannot have array of generics, so this line generates
+ // a compiler warning, just grimace and move on :oP
+ threadNum2eid2c = new Hashtable[numThreads];
+
+ for( int i = 0; i < numThreads; i++ ) {
+ threadNum2eid2c[i] = new Hashtable<Integer, Counter>();
+ readThread( i );
+ }
}
+
- 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 ) {
+
+ BufferedInputStream stream = threadNum2stream [tNum];
+ int numWords = threadNum2numWords [tNum];
+ Event[] stack = threadNum2eventStack[tNum];
+ Hashtable<Integer, Counter> eid2c = threadNum2eid2c [tNum];
+
+ int depth = 0;
+ long timeStamp = 0;
+ int i = 0;
+
+ while( i < numWords ) {
+
+ int event = readInt ( stream );
+ timeStamp = readLong( stream );
+ i += 3;
+
+ int eventType = event & CP_EVENT_MASK;
+ int eventID = event >> CP_EVENT_BASESHIFT;
+
+ switch( eventType ) {
+
+ case CP_EVENTTYPE_BEGIN: {
+ Counter counter = eid2c.get( eventID );
+ if( counter == null ) {
+ counter = new Counter();
+ eid2c.put( eventID, counter );
+ }
+ counter.count++;
+ if( stack[depth] == null ) {
+ stack[depth] = new Event( timeStamp, eventID, counter );
+ } else {
+ stack[depth].timeStamp = timeStamp;
+ stack[depth].eventID = eventID;
+ stack[depth].counter = counter;
+ }
+ depth++;
+ if( depth == STACKMAX ) {
+ throw new Error( "Event stack overflow\n" );
+ }
+ } break;
+
+ case CP_EVENTTYPE_END: {
+ depth--;
+ if( depth < 0 ) {
+ throw new Error( "Event stack underflow\n" );
+ }
+ Event e = stack[depth];
+ long elapsedTime = timeStamp - e.timeStamp;
+ Counter c = e.counter;
+ c.totalTime += elapsedTime;
+ c.selfTime += elapsedTime;
+ if( depth - 1 >= 0 ) {
+ Counter cParent = stack[depth-1].counter;
+ cParent.selfTime -= elapsedTime;
+ }
+ } break;
}
}
- if (depth!=0) {
+
+
+ if( depth != 0 ) {
+ System.out.println( "Warning: unmatched event begin/end\n" );
+ /*
//get rid of last item also
depth--;
Event e=stack[depth];
if(depth-1>=0) {
Counter cn=stack[depth-1].counter;
cn.selftime-=elapsedtime;
- }
+ }
+ */
}
}
- 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;
+
+ 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 ) {
+ throw new Error();
+ }
+ return retval;
+
+ } catch( Exception e ) {
+ throw new Error();
}
- counter.count++;
- if (stack[depth]==null) {
- stack[depth]=new Event(time,event);
- stack[depth].counter=counter;
- } else {
- stack[depth].time=time;
- stack[depth].event=event;
- stack[depth].counter=counter;
+ }
+
+
+ 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 ) {
+ throw new Error();
}
}
- 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() {
+
+ for( int i = 0; i < numThreads; ++i ) {
+
+ System.out.println( "Thread "+i );
+
+ for( Iterator<Integer> evit = threadNum2eid2c[i].keySet().iterator();
+ evit.hasNext();
+ ) {
+ Integer event = evit.next();
+ Counter c = threadNum2eid2c[i].get( event );
+ String eventname = eid2name.containsKey( event ) ?
+ eid2name.get( event ) :
+ Integer.toString( event );
+
+ float tSelf_s = new Long( c.selfTime ).floatValue() / 1000000.0f;
+ float tTotal_s = new Long( c.totalTime ).floatValue() / 1000000.0f;
+
+ System.out.println( "Event: "+eventname+
+ " self time=" +tSelf_s+
+ " total time="+tTotal_s+
+ " count="+c.count
+ );
+ }
+ System.out.println("----------------------------------------------------");
+ }
}
+
}
#include "runtime.h"
-#ifndef CP_MAXEVENTS
-#define CP_MAXEVENTS (1024*1024*128)
+#ifndef CP_MAXEVENTWORDS
+//#define CP_MAXEVENTWORDS (1024*1024*128)
+#define CP_MAXEVENTWORDS (1024*128)
#endif
#define CP_EVENTID_TASKSTALLMEM 6
+extern __thread int cp_threadnum;
+extern __thread struct coreprofmonitor* cp_monitor;
+extern struct coreprofmonitor* cp_monitorList;
+
+
struct coreprofmonitor {
struct coreprofmonitor* next;
- // index for next empty slot in the following arrays
- int numEvents;
- unsigned int events [CP_MAXEVENTS];
- long long logTimes_ms[CP_MAXEVENTS];
+ // index for next unused word in the following array;
+ // individual events may use a variable number of
+ // words to store information
+ int numWords;
+ unsigned int data[CP_MAXEVENTWORDS];
};
-extern __thread int cp_threadnum;
-extern __thread struct coreprofmonitor* cp_monitor;
-extern struct coreprofmonitor* cp_monitorList;
-
-
#ifndef COREPROF_CHECKOVERFLOW
-// normal, no overflow check version
-#define CP_LOGEVENT( eventID, eventType ) { \
- cp_monitor->events[cp_monitor->numEvents] = \
- ((eventID<<CP_EVENT_BASESHIFT)|eventType); \
- cp_monitor->logTimes_ms[cp_monitor->numEvents] = rdtsc(); \
- cp_monitor->numEvents++; \
-}
+#define CP_CHECKOVERFLOW ;
#else
-// check for event overflow, DEBUG ONLY!
-void cp_reportOverflow();
+#define CP_CHECKOVERFLOW if \
+ ( cp_monitor->numWords == CP_MAXEVENTWORDS ) \
+ { cp_reportOverflow(); }
+#endif
+
+
#define CP_LOGEVENT( eventID, eventType ) { \
- if( cp_monitor->numEvents == CP_MAXEVENTS ) \
- { cp_reportOverflow(); } \
- cp_monitor->events[cp_monitor->numEvents] = \
- ((eventID<<CP_EVENT_BASESHIFT)|eventType); \
- cp_monitor->logTimes_ms[cp_monitor->numEvents] = rdtsc(); \
- cp_monitor->numEvents++; \
+ CP_CHECKOVERFLOW; \
+ cp_monitor->data[cp_monitor->numWords] = \
+ ((eventID << CP_EVENT_BASESHIFT) | eventType); \
+ cp_monitor->numWords += 1; \
+ CP_LOGTIME; \
}
-#endif
+
+
+#define CP_LOGTIME CP_CHECKOVERFLOW; \
+ *((long long *)&cp_monitor->data[cp_monitor->numWords]) = rdtsc(); \
+ cp_monitor->numWords += 2;
+
#define CP_CREATE() cp_create();
void cp_create();
void cp_exit();
void cp_dump();
-
+void cp_reportOverflow();
static inline void* cp_calloc( int size ) {