diff --git a/tools/perf.py b/tools/perf.py index 52e7f2172..82e0713cd 100755 --- a/tools/perf.py +++ b/tools/perf.py @@ -3,7 +3,9 @@ from __future__ import print_function import argparse import csv import os +import shlex import signal +import socket import subprocess import sys import time @@ -65,6 +67,49 @@ class GameClockTest(PerfTest): def get_args(self): return ['-F', str(self.frames)] +class PerfServer(object): + ITERATIONS_PER_INSTANCE = 50 + + def __init__(self, address, command=None): + s = address.rsplit(':', 1) + if len(s) == 1: + self.address = (s[0], 7216) + else: + self.address = (s[0], s[1]) + if command: + self.command = shlex.split(command) + self.iterations = self.ITERATIONS_PER_INSTANCE + self.socket = None + self.results = [] + self.reader = None + + def _start(self, test): + if self.command: + server_command = list(self.command) + else: + server_command = [os.path.join(os.getcwd(), PerfTest.EXECUTABLE)] + server_command.extend(['--', '-PD', '0']) + if (hasattr(test, "frames")): + server_command.extend(['-F', str(test.frames)]) + subprocess.check_call(server_command) + time.sleep(4) + self.socket = socket.create_connection(self.address, timeout=1000) + self.reader = csv.DictReader(self.socket.makefile()) + + def run(self, test): + if not self.socket: + self._start(test) + self.socket.send(os.path.join("/perfroms", test.rom)) + self.results.append(next(self.reader)) + self.iterations -= 1 + if self.iterations == 0: + self.socket.send("\n"); + self.reader = None + self.socket.close() + time.sleep(5) + self.socket = None + self.iterations = self.ITERATIONS_PER_INSTANCE + class Suite(object): def __init__(self, cwd, wall=None, game=None, renderer='software'): self.cwd = cwd @@ -72,11 +117,15 @@ class Suite(object): self.wall = wall self.game = game self.renderer = renderer + self.server = None + + def set_server(self, server): + self.server = server def collect_tests(self): roms = [] for f in os.listdir(self.cwd): - if f.endswith('.gba') or f.endswith('.zip'): + if f.endswith('.gba') or f.endswith('.zip') or f.endswith('.gbc') or f.endswith('.gb'): roms.append(f) roms.sort() for rom in roms: @@ -90,15 +139,21 @@ class Suite(object): def run(self): results = [] + sock = None for test in self.tests: print('Running test {}'.format(test.name), file=sys.stderr) - try: - test.run(self.cwd) - except KeyboardInterrupt: - print('Interrupted, returning early...', file=sys.stderr) - return results - if test.results: - results.append(test.results) + if self.server: + self.server.run(test) + else: + try: + test.run(self.cwd) + except KeyboardInterrupt: + print('Interrupted, returning early...', file=sys.stderr) + return results + if test.results: + results.append(test.results) + if self.server: + results.extend(self.server.results) return results if __name__ == '__main__': @@ -106,11 +161,19 @@ if __name__ == '__main__': parser.add_argument('-w', '--wall-time', type=float, default=0, metavar='TIME', help='wall-clock time') parser.add_argument('-g', '--game-frames', type=int, default=0, metavar='FRAMES', help='game-clock frames') parser.add_argument('-N', '--disable-renderer', action='store_const', const=True, help='disable video rendering') + parser.add_argument('-s', '--server', metavar='ADDRESS', help='run on server') + parser.add_argument('-S', '--server-command', metavar='COMMAND', help='command to launch server') parser.add_argument('-o', '--out', metavar='FILE', help='output file path') parser.add_argument('directory', help='directory containing ROM files') args = parser.parse_args() s = Suite(args.directory, wall=args.wall_time, game=args.game_frames, renderer=None if args.disable_renderer else 'software') + if args.server: + if args.server_command: + server = PerfServer(args.server, args.server_command) + else: + server = PerfServer(args.server) + s.set_server(server) s.collect_tests() results = s.run() fout = sys.stdout