Add basic benchmarking script (#83)

* add basic benchmarking script

* add results class, collect more information, and fix check for no args

* fix indentation

* we don't have logger here

* use argv[0] for name of program

* allow dumping of stats from the API and use .format()

* add ProfilingResults class

* bugfixes
This commit is contained in:
JP Smith 2017-03-28 11:12:36 -05:00 committed by GitHub
parent e3f6c8e4ba
commit 1ad9a88032
2 changed files with 74 additions and 19 deletions

View File

@ -6,6 +6,7 @@ import cPickle
import cProfile
import random
import logging
import pstats
import traceback
import signal
import weakref
@ -68,6 +69,24 @@ def sync(f):
self._lock.release()
return newFunction
class ProfilingResults(object):
def __init__(self, raw_stats, instructions_executed):
self.raw_stats = raw_stats
self.instructions_executed = instructions_executed
self.time_elapsed = raw_stats.total_tt
self.loading_time = 0
self.saving_time = 0
self.solver_time = 0
for (func_file, _, func_name), (_, _, _, func_time, _) in raw_stats.stats.iteritems():
if func_name == '_getState':
self.loading_time += func_time
elif func_name == '_putState':
self.saving_time += func_time
elif func_file.endswith('solver.py') and 'setstate' not in func_name and 'getstate' not in func_name and 'ckl' not in func_name:
self.solver_time += func_time
class Executor(object):
def shutdown(self):
@ -173,26 +192,14 @@ class Executor(object):
How long it actually took (tottime: excludes the times of other functions) -
What functions it called (callers) -
What functions called it (callees)'''
results = ProfilingResults(ps, self.count)
getstate_time = 0.0
putstate_time = 0.0
solver_time = 0.0
for (func_file, func_line, func_name), (cc, nc, tt, ct, callers) in ps.stats.iteritems():
#This if tries to sum only independient stuff
if func_name == '_getState':
getstate_time += ct
elif func_name == '_putState':
putstate_time += ct
elif func_file.endswith('solver.py') and 'setstate' not in func_name and 'getstate' not in func_name and 'ckl' not in func_name:
solver_time += ct
#print (func_file, func_line, func_name), (cc, nc, tt, ct)
logger.info("Total profiled time: %f", ps.total_tt)
logger.info("Loading state time: %f", getstate_time)
logger.info("Saving state time: %f", putstate_time)
logger.info("Solver time: %f", solver_time)
logger.info("Other time: %f", ps.total_tt - (getstate_time+putstate_time+solver_time))
logger.info("Total profiled time: %f", results.time_elapsed)
logger.info("Loading state time: %f", results.loading_time)
logger.info("Saving state time: %f", results.saving_time)
logger.info("Solver time: %f", results.solver_time)
logger.info("Other time: %f", results.time_elapsed - (results.loading_time + results.saving_time + results.solver_time))
return results
def _getFilename(self, filename):
return os.path.join(self.workspace, filename)

48
scripts/benchmark.py Normal file
View File

@ -0,0 +1,48 @@
from manticore import Manticore
from sys import argv, exit
def display(results):
print " Total time: {} seconds".format(results.time_elapsed)
print " Total instructions executed: {}".format(results.instructions_executed)
print " Average instructions per second: {}".format(results.instructions_executed / results.time_elapsed)
print " Time spent loading states: {} seconds".format(results.loading_time)
print " Time spent saving states: {} seconds".format(results.saving_time)
print " Time spent in solver: {} seconds".format(results.solver_time)
def benchmark(program):
print "[*] Benchmarking program \"{}\"".format(program)
m = Manticore(program)
m.should_profile = True
m.run()
results = m._executor.dump_stats()
if results is None:
print "[*] Failed to collect stats for program {}".format(program)
return
display(results)
return results
if __name__ == "__main__":
args = argv[1:]
if len(args) == 0:
print "usage: python {} PROGRAM1 PROGRAM2...".format(argv[0])
exit()
first_program = args[0]
other_programs = args[1:]
overall_results = benchmark(first_program)
if other_programs:
for program in other_programs:
results = benchmark(program)
overall_results.time_elapsed += results.time_elapsed
overall_results.instructions_executed += results.instructions_executed
overall_results.solver_time += results.solver_time
overall_results.loading_time += results.loading_time
overall_results.saving_time += results.saving_time
print "Overall:"
display(overall_results)