| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- #!/usr/bin/env python2.7
- # Copyright (C) Microsoft Corporation. All rights reserved.
- # This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details.
- """Analyses the ETW dump file fors dxcompiler output as generated by hcttrace."""
- import argparse
- import datetime
- import xml.etree.ElementTree as ET
- # Task values.
- DXCompilerInitialization = 1;
- DXCompilerShutdown = 2;
- DXCompilerCreateInstance = 3;
- DXCompilerIntelliSenseParse = 4;
- DXCompilerCompile = 5;
- DXCompilerPreprocess = 6;
- DXCompilerDisassemble = 7;
- # Opcode values
- OpcodeStart = 1;
- OpcodeStop = 2;
- # Namespace dictionary.
- ns = {'e': 'http://schemas.microsoft.com/win/2004/08/events/event'}
- def write_basic_info(node):
- '''Writes computer information'''
- print("Basic information:")
- print("CPU Speed: %s" % node.find("e:Data[@Name='CPUSpeed']", ns). text)
- print("Processor count: %s" % node.find("e:Data[@Name='NumberOfProcessors']", ns). text)
- print("Events lost: %s" % node.find("e:Data[@Name='EventsLost']", ns). text)
- print("Pointer size: %s" % node.find("e:Data[@Name='PointerSize']", ns). text)
- def write_compile_times(root):
- '''Prints out compilation times.'''
- compilations = {}
- for e in root:
- system_node = e.find("e:System", ns)
- if system_node is None:
- continue
- channel = system_node.find("e:Channel", ns)
- if channel is None or channel.text <> "Microsoft-Windows-DXCompiler-API/Analytic":
- continue
- task = int(system_node.find("e:Task", ns).text)
- opcode = int(system_node.find("e:Opcode", ns).text)
- pid = int(system_node.find("e:Execution", ns).attrib['ProcessID'])
- tid = int(system_node.find("e:Execution", ns).attrib['ThreadID'])
- time_created = system_node.find("e:TimeCreated", ns).attrib['SystemTime']
- # Something like:
- # 2016-02-02T00:10:51.619434100Z
- # Unfortunately datetime doesn't have enough precision, so we make do with this:
- # 2016-02-02T00:10:39.630081
- if task == DXCompilerCompile:
- time_created = time_created[:26]
- cid = '{0},{1}'.format(pid, tid)
- parsed_time_created = datetime.datetime.strptime(time_created, "%Y-%m-%dT%H:%M:%S.%f")
- if opcode == OpcodeStart:
- #print "Start at %s" % time_created
- compilations[cid] = parsed_time_created
- else:
- old_parsed_time_created = compilations[cid]
- print "Compilation took %s" % str(parsed_time_created - old_parsed_time_created)
- def main():
- parser = argparse.ArgumentParser(description=__doc__)
- parser.add_argument('-v', '--verbose', action='store_true',
- help='Show verbose output')
- parser.add_argument('dumpfiles', nargs='+')
- args = parser.parse_args()
- for dumpfile in args.dumpfiles:
- if args.verbose:
- print >>sys.stderr, 'Scanning for dxcompiler events in dumpfile: %s' % (dumpfile,)
- tree = ET.parse(dumpfile)
- root = tree.getroot()
- write_basic_info(root.find('e:Event/e:EventData', ns))
- write_compile_times(root)
- # Other interesting things:
- # errors, working set, additional stats
- if __name__ == '__main__':
- main()
|