stats.py revision 1596
1#!/usr/bin/env python 2from __future__ import division 3import re, sys, math 4 5 6def usage(): 7 print '''\ 8Usage: %s [-E] [-F] [-d <db> ] [-g <get> ] [-h <host>] [-p] 9 [-s <system>] [-r <runs> ] [-T <samples>] [-u <username>] 10 <command> [command args] 11 12 commands extra parameters description 13 ----------- ------------------ --------------------------------------- 14 bins [regex] List bins (only matching regex) 15 formula <formula> Evaluated formula specified 16 formulas [regex] List formulas (only matching regex) 17 runs none List all runs in database 18 samples none List samples present in database 19 stability <pairnum> <stats> Calculated statistical info about stats 20 stat <regex> Show stat data (only matching regex) 21 stats [regex] List all stats (only matching regex) 22 23 database <command> Where command is drop, init, or clean 24 25''' % sys.argv[0] 26 sys.exit(1) 27 28def getopts(list, flags): 29 import getopt 30 try: 31 opts, args = getopt.getopt(list, flags) 32 except getopt.GetoptError: 33 usage() 34 35 return opts, args 36 37def printval(name, value, invert = False): 38 if invert and value != 0.0: 39 value = 1 / value 40 41 if value == (1e300*1e300): 42 return 43 44 if printval.mode == 'G': 45 print '%s: %g' % (name, value) 46 elif printval.mode != 'F' and value > 1e6: 47 print '%s: %0.5e' % (name, value) 48 else: 49 print '%s: %f' % (name, value) 50 51printval.mode = 'G' 52 53def unique(list): 54 set = {} 55 map(set.__setitem__, list, []) 56 return set.keys() 57 58def graphdata68(runs, options, tag, label, value): 59 import info 60 configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ] 61 benchmarks = [ 'm', 's', 'snt', 'nb1', 'w1', 'w2', 'w3', 'w4', 'nm', 'ns', 'nw1', 'nw2', 'nw3' ] 62 dmas = [ 'x' ] 63 caches = [ '2', '4' ] 64 65 names = [] 66 67 bench_system = { 68 'm' : 'client', 69 's' : 'client', 70 'snt' : 'client', 71 'nb1' : 'server', 72 'nb2' : 'server', 73 'nt1' : 'server', 74 'nt2' : 'server', 75 'w1' : 'server', 76 'w2' : 'server', 77 'w3' : 'server', 78 'w4' : 'server', 79 'w1s' : 'server', 80 'w2s' : 'server', 81 'w3s' : 'server', 82 'ns' : 'natbox', 83 'nm' : 'natbox', 84 'nw1' : 'natbox', 85 'nw2' : 'natbox', 86 'nw3' : 'natbox' 87 } 88 89 for bench in benchmarks: 90 if bench_system[bench] != options.system: 91 continue 92 93 for dma in dmas: 94 for cache in caches: 95 names.append([bench, dma, cache]) 96 97 for bench,dma,cache in names: 98 base = '%s.%s.%s' % (bench, dma, cache) 99 fname = 'data/%s.%s.68.dat' % (tag, base) 100 f = open(fname, 'w') 101 print >>f, '#set TITLE = ' 102 print >>f, '#set ylbl = %s' % label 103 #print >>f, '#set sublabels = %s' % ' '.join(configs) 104 print >>f, '#set sublabels = ste hte htd ocm occ ocs' 105 106 for speed,freq in zip(['s', '6', '8', 'q'],['4GHz', '6GHz','8GHz', '10GHz']): 107 print >>f, '"%s"' % freq, 108 for conf in configs: 109 name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed) 110 run = info.source.allRunNames[name] 111 info.display_run = run.run; 112 val = float(value) 113 if val == 1e300*1e300: 114 print >>f, 0.0, 115 else: 116 print >>f, "%f" % val, 117 print >>f 118 f.close() 119 120def graphdata(runs, options, tag, label, value): 121 if options.graph68: 122 graphdata68(runs, options, tag, label, value) 123 return 124 125 import info 126 configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ] 127 #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'nt2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'nw2', 'nw3' ] 128 #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'w1', 'w2', 'w3', 'ns', 'nm', 'w1s' ] 129 benchmarks = [ 'm', 's', 'nb1', 'nb2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'snt' ] 130 #dmas = [ 'x', 'd', 'b' ] 131 dmas = [ 'x' ] 132 caches = [ '2', '4' ] 133 134 names = [] 135 136 bench_system = { 137 'm' : 'client', 138 's' : 'client', 139 'snt' : 'client', 140 'nb1' : 'server', 141 'nb2' : 'server', 142 'nt1' : 'server', 143 'nt2' : 'server', 144 'w1' : 'server', 145 'w2' : 'server', 146 'w3' : 'server', 147 'w4' : 'server', 148 'w1s' : 'server', 149 'w2s' : 'server', 150 'w3s' : 'server', 151 'ns' : 'natbox', 152 'nm' : 'natbox', 153 'nw1' : 'natbox', 154 'nw2' : 'natbox', 155 'nw3' : 'natbox' 156 } 157 158 for bench in benchmarks: 159 if bench_system[bench] != options.system: 160 continue 161 162 for dma in dmas: 163 for cache in caches: 164 names.append([bench, dma, cache]) 165 166 for bench,dma,cache in names: 167 base = '%s.%s.%s' % (bench, dma, cache) 168 fname = 'data/%s.%s.dat' % (tag, base) 169 f = open(fname, 'w') 170 print >>f, '#set TITLE = ' 171 print >>f, '#set ylbl = %s' % label 172 #print >>f, '#set sublabels = %s' % ' '.join(configs) 173 print >>f, '#set sublabels = ste hte htd ocm occ ocs' 174 175 for speed,freq in zip(['s', 'q'],['4GHz','10GHz']): 176 print >>f, '"%s"' % freq, 177 for conf in configs: 178 name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed) 179 run = info.source.allRunNames[name] 180 info.display_run = run.run; 181 val = float(value) 182 if val == 1e300*1e300: 183 print >>f, 0.0, 184 else: 185 print >>f, "%f" % val, 186 print >>f 187 f.close() 188 189def printdata(runs, value, invert = False): 190 import info 191 for run in runs: 192 info.display_run = run.run; 193 val = float(value) 194 printval(run.name, val) 195 196class CommandException(Exception): 197 pass 198 199def commands(options, command, args): 200 if command == 'database': 201 if len(args) == 0: raise CommandException 202 203 import dbinit 204 mydb = dbinit.MyDB(options) 205 206 if args[0] == 'drop': 207 if len(args) > 2: raise CommandException 208 mydb.admin() 209 mydb.drop() 210 if len(args) == 2 and args[1] == 'init': 211 mydb.create() 212 mydb.connect() 213 mydb.populate() 214 mydb.close() 215 return 216 217 if args[0] == 'init': 218 if len(args) > 1: raise CommandException 219 mydb.admin() 220 mydb.create() 221 mydb.connect() 222 mydb.populate() 223 mydb.close() 224 return 225 226 if args[0] == 'clean': 227 if len(args) > 1: raise CommandException 228 mydb.connect() 229 mydb.clean() 230 return 231 232 raise CommandException 233 234 import db, info 235 info.source = db.Database() 236 info.source.host = options.host 237 info.source.db = options.db 238 info.source.passwd = options.passwd 239 info.source.user = options.user 240 info.source.connect() 241 info.source.update_dict(globals()) 242 243 if type(options.get) is str: 244 info.source.get = options.get 245 246 if options.runs is None: 247 runs = info.source.allRuns 248 else: 249 rx = re.compile(options.runs) 250 runs = [] 251 for run in info.source.allRuns: 252 if rx.match(run.name): 253 runs.append(run) 254 255 info.display_run = runs[0].run 256 257 if command == 'runs': 258 user = None 259 opts, args = getopts(args, '-u') 260 if len(args): 261 raise CommandException 262 for o,a in opts: 263 if o == '-u': 264 user = a 265 info.source.listRuns(user) 266 return 267 268 if command == 'stability': 269 if len(args) < 2: 270 raise CommandException 271 272 try: 273 merge = int(args[0]) 274 except ValueError: 275 usage() 276 stats = info.source.getStat(args[1]) 277 info.source.get = "sum" 278 279 280 #loop through all the stats selected 281 for stat in stats: 282 283 print "%s:" % stat.name 284 print "%-20s %12s %12s %4s %5s %5s %5s %10s" % \ 285 ("run name", "average", "stdev", ">10%", ">1SDV", ">2SDV", "SAMP", "CV") 286 print "%-20s %12s %12s %4s %5s %5s %5s %10s" % \ 287 ("--------------------", "------------", 288 "------------", "----", "-----", "-----", "-----", "----------") 289 #loop through all the selected runs 290 for run in runs: 291 info.display_run = run.run; 292 runTicks = info.source.retTicks([ run ]) 293 #throw away the first one, it's 0 294 runTicks.pop(0) 295 info.globalTicks = runTicks 296 avg = 0 297 stdev = 0 298 numoutsideavg = 0 299 numoutside1std = 0 300 numoutside2std = 0 301 pairRunTicks = [] 302 if float(stat) == 1e300*1e300: 303 continue 304 for t in range(0, len(runTicks)-(merge-1), merge): 305 tempPair = [] 306 for p in range(0,merge): 307 tempPair.append(runTicks[t+p]) 308 pairRunTicks.append(tempPair) 309 #loop through all the various ticks for each run 310 for tick in pairRunTicks: 311 info.globalTicks = tick 312 avg += float(stat) 313 avg /= len(pairRunTicks) 314 for tick in pairRunTicks: 315 info.globalTicks = tick 316 val = float(stat) 317 stdev += pow((val-avg),2) 318 stdev = math.sqrt(stdev / len(pairRunTicks)) 319 for tick in pairRunTicks: 320 info.globalTicks = tick 321 val = float(stat) 322 if (val < (avg * .9)) or (val > (avg * 1.1)): 323 numoutsideavg += 1 324 if (val < (avg - stdev)) or (val > (avg + stdev)): 325 numoutside1std += 1 326 if (val < (avg - (2*stdev))) or (val > (avg + (2*stdev))): 327 numoutside2std += 1 328 if avg > 1000: 329 print "%-20s %12s %12s %4s %5s %5s %5s %10s" % \ 330 (run.name, "%.1f" % avg, "%.1f" % stdev, 331 "%d" % numoutsideavg, "%d" % numoutside1std, 332 "%d" % numoutside2std, "%d" % len(pairRunTicks), 333 "%.3f" % (stdev/avg*100)) 334 elif avg > 100: 335 print "%-20s %12s %12s %4s %5s %5s %5s %10s" % \ 336 (run.name, "%.1f" % avg, "%.1f" % stdev, 337 "%d" % numoutsideavg, "%d" % numoutside1std, 338 "%d" % numoutside2std, "%d" % len(pairRunTicks), 339 "%.5f" % (stdev/avg*100)) 340 else: 341 print "%-20s %12s %12s %4s %5s %5s %5s %10s" % \ 342 (run.name, "%.5f" % avg, "%.5f" % stdev, 343 "%d" % numoutsideavg, "%d" % numoutside1std, 344 "%d" % numoutside2std, "%d" % len(pairRunTicks), 345 "%.7f" % (stdev/avg*100)) 346 return 347 348 if command == 'stats': 349 if len(args) == 0: 350 info.source.listStats() 351 elif len(args) == 1: 352 info.source.listStats(args[0]) 353 else: 354 raise CommandException 355 356 return 357 358 if command == 'stat': 359 if len(args) != 1: 360 raise CommandException 361 362 stats = info.source.getStat(args[0]) 363 for stat in stats: 364 if options.graph: 365 graphdata(runs, options, stat.name, stat.name, stat) 366 else: 367 if options.ticks: 368 print 'only displaying sample %s' % options.ticks 369 info.globalTicks = [ int(x) for x in options.ticks.split() ] 370 371 if options.binned: 372 print 'kernel ticks' 373 stat.bins = 'kernel' 374 printdata(runs, stat) 375 376 print 'idle ticks' 377 stat.bins = 'idle' 378 printdata(runs, stat) 379 380 print 'user ticks' 381 stat.bins = 'user' 382 printdata(runs, stat) 383 384 print 'interrupt ticks' 385 stat.bins = 'interrupt' 386 printdata(runs, stat) 387 388 print 'total ticks' 389 390 stat.bins = None 391 print stat.name 392 printdata(runs, stat) 393 return 394 395 if command == 'formula': 396 if len(args) != 1: 397 raise CommandException 398 399 stats = eval(args[0]) 400 for stat in stats: 401 if options.graph: 402 graphdata(runs, options, stat.name, stat.name, stat) 403 else: 404 if options.binned: 405 print 'kernel ticks' 406 stat.bins = 'kernel' 407 printdata(runs, stat) 408 409 print 'idle ticks' 410 stat.bins = 'idle' 411 printdata(runs, stat) 412 413 print 'user ticks' 414 stat.bins = 'user' 415 printdata(runs, stat) 416 417 print 'interrupt ticks' 418 stat.bins = 'interrupt' 419 printdata(runs, stat) 420 421 print 'total ticks' 422 423 stat.bins = None 424 print args[0] 425 printdata(runs, stat) 426 return 427 428 if command == 'bins': 429 if len(args) == 0: 430 info.source.listBins() 431 elif len(args) == 1: 432 info.source.listBins(args[0]) 433 else: 434 raise CommandException 435 436 return 437 438 if command == 'formulas': 439 if len(args) == 0: 440 info.source.listFormulas() 441 elif len(args) == 1: 442 info.source.listFormulas(args[0]) 443 else: 444 raise CommandException 445 446 return 447 448 if command == 'samples': 449 if len(args): 450 raise CommandException 451 452 info.source.listTicks(runs) 453 return 454 455 if len(args): 456 raise CommandException 457 458 system = info.source.__dict__[options.system] 459 460 if command == 'usertime': 461 import copy 462 kernel = copy.copy(system.full_cpu.numCycles) 463 kernel.bins = 'kernel' 464 465 user = copy.copy(system.full_cpu.numCycles) 466 user.bins = 'user' 467 468 if options.graph: 469 graphdata(runs, options, 'usertime', 'User Fraction', 470 user / system.full_cpu.numCycles) 471 else: 472 printdata(runs, user / system.full_cpu.numCycles) 473 return 474 475 if command == 'ticks': 476 if options.binned: 477 print 'kernel ticks' 478 system.full_cpu.numCycles.bins = 'kernel' 479 printdata(runs, system.full_cpu.numCycles) 480 481 print 'idle ticks' 482 system.full_cpu.numCycles.bins = 'idle' 483 printdata(runs, system.full_cpu.numCycles) 484 485 print 'user ticks' 486 system.full_cpu.numCycles.bins = 'user' 487 printdata(runs, system.full_cpu.numCycles) 488 489 print 'total ticks' 490 491 system.full_cpu.numCycles.bins = None 492 printdata(runs, system.full_cpu.numCycles) 493 return 494 495 if command == 'packets': 496 packets = system.tsunami.etherdev.rxPackets 497 if options.graph: 498 graphdata(runs, options, 'packets', 'Packets', packets) 499 else: 500 printdata(runs, packets) 501 return 502 503 if command == 'ppt' or command == 'tpp': 504 ppt = system.tsunami.etherdev.rxPackets / sim_ticks 505 printdata(runs, ppt, command == 'tpp') 506 return 507 508 if command == 'pps': 509 pps = system.tsunami.etherdev.rxPackets / sim_seconds 510 if options.graph: 511 graphdata(runs, options, 'pps', 'Packets/s', pps) 512 else: 513 printdata(runs, pps) 514 return 515 516 if command == 'bpt' or command == 'tpb': 517 bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes 518 bpt = bytes / sim_ticks * 8 519 if options.graph: 520 graphdata(runs, options, 'bpt', 'bps / Hz', bpt) 521 else: 522 printdata(runs, bpt, command == 'tpb') 523 return 524 525 if command == 'bptb' or command == 'tpbb': 526 bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes 527 528 print 'kernel stats' 529 bytes.bins = 'kernel' 530 printdata(runs, bytes / ticks) 531 532 print 'idle stats' 533 bytes.bins = 'idle' 534 printdata(runs, bytes / ticks) 535 536 print 'user stats' 537 bytes.bins = 'user' 538 printdata(runs, bytes / ticks) 539 540 return 541 542 if command == 'bytes': 543 stat = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes 544 545 if options.binned: 546 print '%s kernel stats' % stat.name 547 stat.bins = 'kernel' 548 printdata(runs, stat) 549 550 print '%s idle stats' % stat.name 551 stat.bins = 'idle' 552 printdata(runs, stat) 553 554 print '%s user stats' % stat.name 555 stat.bins = 'user' 556 printdata(runs, stat) 557 558 print '%s total stats' % stat.name 559 stat.bins = None 560 561 printdata(runs, stat) 562 return 563 564 if command == 'rxbps': 565 gbps = system.tsunami.etherdev.rxBandwidth / 1e9 566 if options.graph: 567 graphdata(runs, options, 'rxbps', 'Bandwidth (Gbps)', gbps) 568 else: 569 printdata(runs, gbps) 570 return 571 572 if command == 'txbps': 573 gbps = system.tsunami.etherdev.txBandwidth / 1e9 574 if options.graph: 575 graphdata(runs, options, 'txbps', 'Bandwidth (Gbps)', gbps) 576 else: 577 printdata(runs, gbps) 578 return 579 580 if command == 'bps': 581 rxbps = system.tsunami.etherdev.rxBandwidth 582 txbps = system.tsunami.etherdev.txBandwidth 583 gbps = (rxbps + txbps) / 1e9 584 if options.graph: 585 graphdata(runs, options, 'bps', 'Bandwidth (Gbps)', gbps) 586 else: 587 printdata(runs, gbps) 588 return 589 590 if command == 'misses': 591 stat = system.L2.overall_mshr_misses 592 if options.binned: 593 print '%s kernel stats' % stat.name 594 stat.bins = 'kernel' 595 printdata(runs, stat) 596 597 print '%s idle stats' % stat.name 598 stat.bins = 'idle' 599 printdata(runs, stat) 600 601 print '%s user stats' % stat.name 602 stat.bins = 'user' 603 printdata(runs, stat) 604 605 print '%s total stats' % stat.name 606 607 stat.bins = None 608 if options.graph: 609 graphdata(runs, options, 'misses', 'Overall MSHR Misses', stat) 610 else: 611 printdata(runs, stat) 612 return 613 614 if command == 'mpkb': 615 misses = system.L2.overall_mshr_misses 616 rxbytes = system.tsunami.etherdev.rxBytes 617 txbytes = system.tsunami.etherdev.txBytes 618 619 if options.binned: 620 print 'mpkb kernel stats' 621 misses.bins = 'kernel' 622 mpkb = misses / ((rxbytes + txbytes) / 1024) 623 printdata(runs, mpkb) 624 625 print 'mpkb idle stats' 626 misses.bins = 'idle' 627 mpkb = misses / ((rxbytes + txbytes) / 1024) 628 printdata(runs, mpkb) 629 630 print 'mpkb user stats' 631 misses.bins = 'user' 632 mpkb = misses / ((rxbytes + txbytes) / 1024) 633 printdata(runs, mpkb) 634 635 print 'mpkb total stats' 636 637 mpkb = misses / ((rxbytes + txbytes) / 1024) 638 misses.bins = None 639 if options.graph: 640 graphdata(runs, options, 'mpkb', 'Misses / KB', mpkb) 641 else: 642 printdata(runs, mpkb) 643 return 644 645 if command == 'ipkb': 646 interrupts = system.full_cpu.kern.faults[4] 647 rxbytes = system.tsunami.etherdev.rxBytes 648 txbytes = system.tsunami.etherdev.txBytes 649 650 if options.binned: 651 print 'ipkb kernel stats' 652 interrupts.bins = 'kernel' 653 ipkb = interrupts / ((rxbytes + txbytes) / 1024) 654 printdata(runs, ipkb) 655 656 print 'ipkb idle stats' 657 interrupts.bins = 'idle' 658 ipkb = interrupts / ((rxbytes + txbytes) / 1024) 659 printdata(runs, ipkb) 660 661 print 'ipkb user stats' 662 interrupts.bins = 'user' 663 ipkb = interrupts / ((rxbytes + txbytes) / 1024) 664 printdata(runs, ipkb) 665 666 print 'ipkb total stats' 667 668 ipkb = interrupts / ((rxbytes + txbytes) / 1024) 669 interrupts.bins = None 670 if options.graph: 671 graphdata(runs, options, 'ipkb', 'Interrupts / KB', ipkb) 672 else: 673 printdata(runs, ipkb) 674 return 675 676 if command == 'execute': 677 printdata(runs, system.full_cpu.ISSUE__count) 678 return 679 680 if command == 'commit': 681 printdata(runs, system.full_cpu.COM__count) 682 return 683 684 if command == 'fetch': 685 printdata(runs, system.full_cpu.FETCH__count) 686 return 687 688 if command == 'bpp': 689 ed = system.tsunami.etherdev 690 bpp = (ed.rxBytes + ed.txBytes) / (ed.rxPackets + ed.txPackets) 691 if options.graph: 692 graphdata(runs, options, 'bpp', 'Bytes / Packet', bpp) 693 else: 694 printdata(runs, bpp) 695 return 696 697 if command == 'rxbpp': 698 bpp = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.rxPackets 699 if options.graph: 700 graphdata(runs, options, 'rxbpp', 'Receive Bytes / Packet', bpp) 701 else: 702 printdata(runs, bpp) 703 return 704 705 if command == 'txbpp': 706 bpp = system.tsunami.etherdev.txBytes / system.tsunami.etherdev.txPackets 707 if options.graph: 708 graphdata(runs, options, 'txbpp', 'Transmit Bytes / Packet', bpp) 709 else: 710 printdata(runs, bpp) 711 return 712 713 if command == 'rtp': 714 rtp = system.tsunami.etherdev.rxPackets / system.tsunami.etherdev.txPackets 715 if options.graph: 716 graphdata(runs, options, 'rtp', 'rxPackets / txPackets', rtp) 717 else: 718 printdata(runs, rtp) 719 return 720 721 if command == 'rtb': 722 rtb = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.txBytes 723 if options.graph: 724 graphdata(runs, options, 'rtb', 'rxBytes / txBytes', rtb) 725 else: 726 printdata(runs, rtb) 727 return 728 729 raise CommandException 730 731 732class Options: pass 733 734if __name__ == '__main__': 735 import getpass 736 737 options = Options() 738 options.host = 'zizzer.pool' 739 options.db = None 740 options.passwd = '' 741 options.user = getpass.getuser() 742 options.runs = None 743 options.system = 'client' 744 options.get = None 745 options.binned = False 746 options.graph = False 747 options.graph68 = False 748 options.ticks = False 749 750 opts, args = getopts(sys.argv[1:], '-6BEFGd:g:h:pr:s:u:T:') 751 for o,a in opts: 752 if o == '-6': 753 options.graph68 = True 754 if o == '-B': 755 options.binned = True 756 if o == '-E': 757 printval.mode = 'E' 758 if o == '-F': 759 printval.mode = 'F' 760 if o == '-G': 761 options.graph = True; 762 if o == '-d': 763 options.db = a 764 if o == '-g': 765 options.get = a 766 if o == '-h': 767 options.host = a 768 if o == '-p': 769 options.passwd = getpass.getpass() 770 if o == '-r': 771 options.runs = a 772 if o == '-u': 773 options.user = a 774 if o == '-s': 775 options.system = a 776 if o == '-T': 777 options.ticks = a 778 779 if len(args) == 0: 780 usage() 781 782 command = args[0] 783 args = args[1:] 784 785 try: 786 commands(options, command, args) 787 except CommandException: 788 usage() 789