6 // everything defined here should match coreprof.h
8 public static final int CP_EVENT_MASK = 3;
9 public static final int CP_EVENT_BASESHIFT = 8;
11 public static final int CP_EVENTTYPE_BEGIN = 1;
12 public static final int CP_EVENTTYPE_END = 2;
13 public static final int CP_EVENTTYPE_ONEOFF = 3;
15 public static final int CP_EVENTID_MAIN = 0x04;
16 public static final int CP_EVENTID_RUNMALLOC = 0x10;
17 public static final int CP_EVENTID_RUNFREE = 0x11;
18 public static final int CP_EVENTID_WORKSCHEDGRAB = 0x20;
19 public static final int CP_EVENTID_TASKDISPATCH = 0x30;
20 public static final int CP_EVENTID_TASKEXECUTE = 0x31;
21 public static final int CP_EVENTID_TASKRETIRE = 0x32;
22 public static final int CP_EVENTID_TASKSTALLVAR = 0x40;
23 public static final int CP_EVENTID_TASKSTALLMEM = 0x41;
27 eid2name = new Hashtable<Integer, String>();
28 eid2name.put( CP_EVENTID_MAIN, "MAIN " );
29 eid2name.put( CP_EVENTID_RUNMALLOC, "RUNMALLOC " );
30 eid2name.put( CP_EVENTID_RUNFREE, "RUNFREE " );
31 eid2name.put( CP_EVENTID_WORKSCHEDGRAB, "WORKSCHEDGRAB" );
32 eid2name.put( CP_EVENTID_TASKDISPATCH, "TASKDISPATCH " );
33 eid2name.put( CP_EVENTID_TASKEXECUTE, "TASKEXECUTE " );
34 eid2name.put( CP_EVENTID_TASKRETIRE, "TASKRETIRE " );
35 eid2name.put( CP_EVENTID_TASKSTALLVAR, "TASKSTALLVAR " );
36 eid2name.put( CP_EVENTID_TASKSTALLMEM, "TASKSTALLMEM " );
39 Hashtable<Integer, String> eid2name;
43 public static void main( String args[] ) {
44 if( args.length != 2 ) {
45 System.out.println( "usage: <coreprof.dat file> <trace out file>" );
48 Trace t = new Trace( args[0], args[1] );
53 // event IDs are a word, timestamps are long ints
54 public static final int WORD_SIZE = 4;
55 public static final int EVENT_SIZE = WORD_SIZE;
56 public static final int TIMESTAMP_SIZE = WORD_SIZE*2;
59 ThreadData[] threadData;
63 public Trace( String inFile, String outFile ) {
65 openInputStreams( inFile );
69 for( int i = 0; i < numThreads; i++ ) {
73 printStats( outFile );
77 public static int readInt( InputStream is ) {
84 int retval = (b4<<24)|(b3<<16)|(b2<<8)|b1;
91 } catch( Exception e ) {
97 public static long readLong( InputStream is ) {
109 (b8<<56)|(b7<<48)|(b6<<40)|(b5<<32)|
110 (b4<<24)|(b3<<16)|(b2<< 8)|b1;
117 } catch( Exception e ) {
123 protected void openInputStreams( String filename ) {
125 BufferedInputStream bis = null;
129 bis = new BufferedInputStream( new FileInputStream( filename ) );
130 offset = readHeader( bis );
132 } catch( Exception e ) {
137 for( int i = 0; i < numThreads; ++i ) {
139 // point a thread's event stream to the
140 // beginning of its data within the input file
141 threadData[i].dataStream =
142 new BufferedInputStream( new FileInputStream( filename ) );
146 skip -= threadData[i].dataStream.skip( skip );
149 offset += WORD_SIZE*threadData[i].numDataWords;
151 } catch( Exception e ) {
159 int readHeader( BufferedInputStream bis ) {
162 int version = readInt( bis );
164 throw new Error( "Unsupported Version" );
166 int offset = WORD_SIZE;
168 // read number of threads
169 numThreads = readInt( bis );
172 threadData = new ThreadData[numThreads];
174 // read number of words used for all events, per thread
175 for( int i = 0; i < numThreads; ++i ) {
176 threadData[i] = new ThreadData();
177 threadData[i].numDataWords = readInt( bis );
184 public void readThread( int tNum ) {
186 System.out.print( "Reading thread "+tNum );
188 ThreadData tdata = threadData[tNum];
189 tdata.stackDepth = 0;
192 int numProgress = 10;
194 int progressChunk = tdata.numDataWords / numProgress;
196 boolean[] progress = new boolean[numProgress];
197 for( j = 0; j < numProgress; ++j ) {
202 while( i < tdata.numDataWords ) {
204 if( !progress[j] && i > j*progressChunk ) {
205 System.out.print( "." );
207 if( j < numProgress - 1 ) {
212 int eventRaw = readInt ( tdata.dataStream );
213 timeStamp = readLong( tdata.dataStream );
216 int eventType = eventRaw & CP_EVENT_MASK;
217 int eventID = eventRaw >> CP_EVENT_BASESHIFT;
219 switch( eventType ) {
221 case CP_EVENTTYPE_BEGIN: {
222 pushEvent( tdata, eventID, timeStamp );
225 case CP_EVENTTYPE_END: {
226 popEvent( tdata, eventID, timeStamp );
232 System.out.println( "" );
234 if( tdata.stackDepth != 0 ) {
235 // worker threads currently do not exit gracefully, and therefore
236 // never register their MAIN END event, so if the mismatch is with
237 // MAIN BEGIN then treat it as fine, otherwise warn.
238 if( tdata.stackDepth == 1 ) {
239 // the value of timestamp will be equal to whatever the last
240 // properly registered event for this thread was
241 popEvent( tdata, CP_EVENTID_MAIN, timeStamp );
243 System.out.println( "Warning: unmatched event begin/end\n" );
249 protected void pushEvent( ThreadData tdata,
253 EventSummary eventSummary = null;
255 if( tdata.stackDepth == 0 ) {
256 // there are no parents, so look in the rootEvents
257 // for an existing EventSummary of this type
258 for( Iterator<EventSummary> itr = tdata.rootEvents.iterator();
261 EventSummary es = itr.next();
262 if( es.eventID == eventID ) {
267 if( eventSummary == null ) {
268 // there is no summary for this event type yet,
270 eventSummary = new EventSummary( eventID );
271 tdata.rootEvents.add( eventSummary );
275 // look through the parent's children for an existing
276 // EventSummary of this type
277 EventSummary esParent = tdata.eventStack.get( tdata.stackDepth - 1 );
278 for( Iterator<EventSummary> itr = esParent.children.iterator();
281 EventSummary es = itr.next();
282 if( es.eventID == eventID ) {
287 if( eventSummary == null ) {
288 // there is no summary for this event type yet,
289 // under this parent, so add it
290 eventSummary = new EventSummary( eventID );
291 esParent.children.add( eventSummary );
292 eventSummary.parent = esParent;
296 eventSummary.timeStampBeginLatestInstance = timeStamp;
298 eventSummary.instanceCount++;
300 if( tdata.eventStack.size() <= tdata.stackDepth ) {
301 tdata.eventStack.setSize( 2*tdata.stackDepth + 20 );
303 tdata.eventStack.set( tdata.stackDepth, eventSummary );
309 protected void popEvent( ThreadData tdata,
313 if( tdata.stackDepth < 0 ) {
314 throw new Error( "Event stack underflow\n" );
317 EventSummary eventSummary = tdata.eventStack.get( tdata.stackDepth );
318 assert eventSummary != null;
321 timeStamp - eventSummary.timeStampBeginLatestInstance;
323 eventSummary.totalTime_ticks += elapsedTime;
324 eventSummary.selfTime_ticks += elapsedTime;
326 if( tdata.stackDepth - 1 >= 0 ) {
327 EventSummary esParent = tdata.eventStack.get( tdata.stackDepth-1 );
328 esParent.selfTime_ticks -= elapsedTime;
334 public void printStats( String filename ) {
336 System.out.println( "Printing..." );
340 new BufferedWriter( new FileWriter( filename ) );
342 for( int i = 0; i < numThreads; ++i ) {
344 ThreadData tdata = threadData[i];
346 bw.write( "----------------------------------\n" );
347 bw.write( "Thread "+i+"\n" );
349 for( Iterator<EventSummary> itr = tdata.rootEvents.iterator();
352 EventSummary es = itr.next();
353 printEventSummary( bw, es, 0 );
361 } catch( IOException e ) {}
365 public void printEventSummary( BufferedWriter bw,
370 String strIndent = "";
371 for( int i = 0; i < depth; ++i ) {
375 String strEventName =
376 eid2name.containsKey( es.eventID ) ?
377 eid2name.get( es.eventID ) :
378 Integer.toString( es.eventID );
380 float tOfParent_perc;
381 String strPercParent = "";
382 if( es.parent != null ) {
383 float divisor = new Long( es.parent.totalTime_ticks ).floatValue();
384 if( divisor <= 0.00001f ) {
390 new Long( es.totalTime_ticks ).floatValue() /
393 strPercParent = String.format( " %%ofParent=%5.1f",
399 new Long( es.selfTime_ticks ).floatValue() /
400 new Long( es.totalTime_ticks ).floatValue();
402 String strSelfStats =
403 String.format( " total(ticks)=%12dK, %%self=%5.1f, count=%d",
404 es.totalTime_ticks/1000,
414 for( Iterator<EventSummary> itr = es.children.iterator();
417 EventSummary esChild = itr.next();
418 printEventSummary( bw, esChild, depth + 1 );