{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "aabc21a9", "metadata": {}, "outputs": [], "source": [ "import itertools\n", "import functools\n", "import contextlib\n", "import base64\n", "from io import BytesIO" ] }, { "cell_type": "code", "execution_count": 2, "id": "3e0f2c2c", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "from matplotlib import pyplot as plt\n", "import xarray as xr\n", "from IPython.display import display, HTML" ] }, { "cell_type": "code", "execution_count": 3, "id": "ebd68f38", "metadata": {}, "outputs": [], "source": [ "import asm\n", "from gtemu import Emulator, RAM, ROM\n", "import benchmark\n", "from benchmark import _read_word as read_word" ] }, { "cell_type": "code", "execution_count": 4, "id": "28118774", "metadata": {}, "outputs": [], "source": [ "# All of these metrics are in cycles\n", "_PER_INSTRUCTION_DATA = ['timeslice_on_entry', 'stall_in_vcpu', 'in_display_loop', 'execution_time', 'timeslice_on_exit']\n", "\n", "_EMPTY_INSTRUCTION_DATA = dict((key, 0) for key in _PER_INSTRUCTION_DATA)\n", "\n", "def _sign_extend(byte):\n", " return (byte & 0b0111_1111) - (byte & 0b1000_0000)\n", "\n", "class Profiler:\n", " \n", " def __init__(self, emulator):\n", " self.emulator = emulator\n", " self._invocation_data = None\n", " self._instruction_data = None\n", " self.invocation_data = []\n", " self.current_invocation_instruction_data = None # Dict of pc -> instruction data\n", " self.current_instruction_data = None # Instruction data\n", " # We use this all the time\n", " self._enter = asm.symbol('ENTER')\n", " # We also need to know when we're about to execute SYS\n", " self._sys = asm.symbol('SYS') & 0xff\n", " # maxTicks, but stored in cycles.\n", " self._max_cycles = 28\n", " self._vticks = 0x15\n", " \n", " def get_cycles_remaining(self):\n", " # We are at ENTER or NEXT.\n", " # If at ENTER, we're at the start of a timeslice and the length is in ac\n", " if self.emulator.next_instruction == self._enter:\n", " ticks_remaining = self.emulator.AC\n", " # if at NEXT, we've just tried an instruction. ac = the negative of the ticks taken.\n", " else:\n", " ticks_remaining = _sign_extend(self.emulator.AC) + RAM[self._vticks]\n", " # In both cases, the ticks remaining is offset by maxTicks\n", " # (and by vCPU_overhead, but that's constant, and so it's grouped as part of the displayloop)\n", " return ticks_remaining * 2 + self._max_cycles\n", " \n", " def get_instruction_about_to_execute(self):\n", " # Assuming we haven't executed next yet\n", " vpc_low, vpc_high = RAM[0x16: 0x18]\n", " return (vpc_low + 2) & 0xff | (vpc_high << 8)\n", " \n", " def begin_invocation(self):\n", " # Set up data structures\n", " self.current_invocation_instruction_data = {}\n", " self.invocation_data.append(self.current_invocation_instruction_data)\n", " \n", " def begin_instruction(self):\n", " # We don't handle loops\n", " instruction = self.get_instruction_about_to_execute()\n", " assert instruction not in self.current_invocation_instruction_data\n", " self.current_invocation_instruction_data[instruction] = self.current_instruction_data = _EMPTY_INSTRUCTION_DATA.copy()\n", " self.current_instruction_data['timeslice_on_entry'] = self.get_cycles_remaining()\n", " \n", " def step_vcpu_with_measurement(self):\n", " # We're about to step, but first, look ahead and see where we're going.\n", " # If we've got time to run an instruction, the time will count towards the instruction runtime.\n", " # If not, any time remaining will count towards stall, and we count two values, stall in vCPU and time in displayloop\n", " remaining_cycles = self.get_cycles_remaining()\n", " # If ticks_remaining >= maxTicks, we'll execute an instruction and time should be accounted as execution\n", " # UNLESS the instruction is SYS. \n", " # If it's a SYS function, we need to check the operand, and if there's no time, it's a stall.\n", " if remaining_cycles >= self._max_cycles:\n", " dest = 'execution_time' \n", " x = self.get_instruction_about_to_execute()\n", " instruction, operand = RAM[x: x+2]\n", " if instruction == self._sys:\n", " if self._max_cycles - _sign_extend(operand) * 2 > remaining_cycles:\n", " dest = 'stall_in_vcpu'\n", " # But otherwise, we're going to return to the display loop.\n", " # We account for this as stall_in_vcpu being remaining_cycles, and the remainder as in_display_loop\n", " else:\n", " self.current_instruction_data['stall_in_vcpu'] += remaining_cycles\n", " self.current_instruction_data['in_display_loop'] -= remaining_cycles\n", " dest = 'in_display_loop'\n", " \n", " self.current_instruction_data[dest] += self.emulator.step_vcpu()\n", " \n", " def end_instruction(self):\n", " self.current_instruction_data['timeslice_on_exit'] = self.get_cycles_remaining()\n", " \n", " def profile_invocation(self):\n", " self.begin_invocation()\n", " target_instruction = self.emulator.vLR\n", " while target_instruction != self.get_instruction_about_to_execute():\n", " self.begin_instruction()\n", " v_pc = self.emulator.vPC # Used to see when we've moved\n", " while v_pc == self.emulator.vPC:\n", " self.step_vcpu_with_measurement()\n", " self.end_instruction()" ] }, { "cell_type": "code", "execution_count": 5, "id": "0a391178", "metadata": {}, "outputs": [], "source": [ "my_symbols = benchmark._load(benchmark.MY_MANDELBROT)" ] }, { "cell_type": "code", "execution_count": 6, "id": "d0532c09", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Boot reached SYS_RESET_88 in 1006781 cycles (0.16108496s)\n", "Boot reached SYS_Exec_88 (Reset) in 1006825 cycles (0.161092s)\n", "Boot reached SYS_Exec_88 (Main) in 2037968 cycles (0.32607488s)\n", "Program was ready to begin exectution after 3741467 cycles (0.5986347200000001s)\n" ] } ], "source": [ "cycles = benchmark._run_to_main_start()" ] }, { "cell_type": "code", "execution_count": 7, "id": "d172bb47", "metadata": {}, "outputs": [], "source": [ "profiler = Profiler(Emulator)\n", "for _ in range(20_000):\n", " cycles += benchmark._run_to_function_entry(my_symbols, 'MulShift8')\n", " profiler.profile_invocation()" ] }, { "cell_type": "code", "execution_count": 8, "id": "b7d194d1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{514: {'timeslice_on_entry': 62,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 16,\n", " 'timeslice_on_exit': 46},\n", " 516: {'timeslice_on_entry': 46,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 20,\n", " 'timeslice_on_exit': 26},\n", " 518: {'timeslice_on_entry': 26,\n", " 'stall_in_vcpu': 26,\n", " 'in_display_loop': 652,\n", " 'execution_time': 28,\n", " 'timeslice_on_exit': 120},\n", " 520: {'timeslice_on_entry': 120,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 28,\n", " 'timeslice_on_exit': 92},\n", " 529: {'timeslice_on_entry': 92,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 16,\n", " 'timeslice_on_exit': 76},\n", " 531: {'timeslice_on_entry': 76,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 28,\n", " 'timeslice_on_exit': 48},\n", " 533: {'timeslice_on_entry': 48,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 28,\n", " 'timeslice_on_exit': 20},\n", " 544: {'timeslice_on_entry': 20,\n", " 'stall_in_vcpu': 20,\n", " 'in_display_loop': 652,\n", " 'execution_time': 22,\n", " 'timeslice_on_exit': 126},\n", " 546: {'timeslice_on_entry': 126,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 16,\n", " 'timeslice_on_exit': 110},\n", " 548: {'timeslice_on_entry': 110,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 22,\n", " 'timeslice_on_exit': 88},\n", " 550: {'timeslice_on_entry': 88,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 16,\n", " 'timeslice_on_exit': 72},\n", " 552: {'timeslice_on_entry': 72,\n", " 'stall_in_vcpu': 72,\n", " 'in_display_loop': 652,\n", " 'execution_time': 120,\n", " 'timeslice_on_exit': 28},\n", " 554: {'timeslice_on_entry': 28,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 20,\n", " 'timeslice_on_exit': 8},\n", " 556: {'timeslice_on_entry': 8,\n", " 'stall_in_vcpu': 8,\n", " 'in_display_loop': 652,\n", " 'execution_time': 22,\n", " 'timeslice_on_exit': 126},\n", " 558: {'timeslice_on_entry': 126,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 16,\n", " 'timeslice_on_exit': 110},\n", " 560: {'timeslice_on_entry': 110,\n", " 'stall_in_vcpu': 110,\n", " 'in_display_loop': 652,\n", " 'execution_time': 120,\n", " 'timeslice_on_exit': 28},\n", " 562: {'timeslice_on_entry': 28,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 20,\n", " 'timeslice_on_exit': 8},\n", " 564: {'timeslice_on_entry': 8,\n", " 'stall_in_vcpu': 8,\n", " 'in_display_loop': 652,\n", " 'execution_time': 22,\n", " 'timeslice_on_exit': 126},\n", " 566: {'timeslice_on_entry': 126,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 16,\n", " 'timeslice_on_exit': 110},\n", " 568: {'timeslice_on_entry': 110,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 92,\n", " 'timeslice_on_exit': 18},\n", " 570: {'timeslice_on_entry': 18,\n", " 'stall_in_vcpu': 18,\n", " 'in_display_loop': 88,\n", " 'execution_time': 16,\n", " 'timeslice_on_exit': 82},\n", " 572: {'timeslice_on_entry': 82,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 20,\n", " 'timeslice_on_exit': 62},\n", " 574: {'timeslice_on_entry': 62,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 28,\n", " 'timeslice_on_exit': 34},\n", " 576: {'timeslice_on_entry': 34,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 20,\n", " 'timeslice_on_exit': 14},\n", " 578: {'timeslice_on_entry': 14,\n", " 'stall_in_vcpu': 14,\n", " 'in_display_loop': 79,\n", " 'execution_time': 22,\n", " 'timeslice_on_exit': 112},\n", " 580: {'timeslice_on_entry': 112,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 16,\n", " 'timeslice_on_exit': 96},\n", " 582: {'timeslice_on_entry': 96,\n", " 'stall_in_vcpu': 96,\n", " 'in_display_loop': 66,\n", " 'execution_time': 120,\n", " 'timeslice_on_exit': 14},\n", " 584: {'timeslice_on_entry': 14,\n", " 'stall_in_vcpu': 14,\n", " 'in_display_loop': 70,\n", " 'execution_time': 28,\n", " 'timeslice_on_exit': 102},\n", " 586: {'timeslice_on_entry': 102,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 20,\n", " 'timeslice_on_exit': 82},\n", " 588: {'timeslice_on_entry': 82,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 20,\n", " 'timeslice_on_exit': 62},\n", " 590: {'timeslice_on_entry': 62,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 28,\n", " 'timeslice_on_exit': 34},\n", " 599: {'timeslice_on_entry': 34,\n", " 'stall_in_vcpu': 0,\n", " 'in_display_loop': 0,\n", " 'execution_time': 20,\n", " 'timeslice_on_exit': 14},\n", " 601: {'timeslice_on_entry': 14,\n", " 'stall_in_vcpu': 14,\n", " 'in_display_loop': 66,\n", " 'execution_time': 20,\n", " 'timeslice_on_exit': 114}}" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profiler.current_invocation_instruction_data" ] }, { "cell_type": "code", "execution_count": 9, "id": "3844a7a2", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
timeslice_on_entrystall_in_vcpuin_display_loopexecution_timetimeslice_on_exit
Instruction
51462001646
51646002026
518262665228120
520120002892
52992001676
53176002848
53348002820
544202065222126
5461260016110
548110002288
55088001672
552727265212028
5542800208
5568865222126
5581260016110
56011011065212028
5622800208
5648865222126
5661260016110
568110009218
5701818881682
57282002062
57462002834
57634002014
57814147922112
580112001696
58296966612014
58414147028102
586102002082
58882002062
59062002834
59934002014
60114146620114
\n", "
" ], "text/plain": [ " timeslice_on_entry stall_in_vcpu in_display_loop \\\n", "Instruction \n", "514 62 0 0 \n", "516 46 0 0 \n", "518 26 26 652 \n", "520 120 0 0 \n", "529 92 0 0 \n", "531 76 0 0 \n", "533 48 0 0 \n", "544 20 20 652 \n", "546 126 0 0 \n", "548 110 0 0 \n", "550 88 0 0 \n", "552 72 72 652 \n", "554 28 0 0 \n", "556 8 8 652 \n", "558 126 0 0 \n", "560 110 110 652 \n", "562 28 0 0 \n", "564 8 8 652 \n", "566 126 0 0 \n", "568 110 0 0 \n", "570 18 18 88 \n", "572 82 0 0 \n", "574 62 0 0 \n", "576 34 0 0 \n", "578 14 14 79 \n", "580 112 0 0 \n", "582 96 96 66 \n", "584 14 14 70 \n", "586 102 0 0 \n", "588 82 0 0 \n", "590 62 0 0 \n", "599 34 0 0 \n", "601 14 14 66 \n", "\n", " execution_time timeslice_on_exit \n", "Instruction \n", "514 16 46 \n", "516 20 26 \n", "518 28 120 \n", "520 28 92 \n", "529 16 76 \n", "531 28 48 \n", "533 28 20 \n", "544 22 126 \n", "546 16 110 \n", "548 22 88 \n", "550 16 72 \n", "552 120 28 \n", "554 20 8 \n", "556 22 126 \n", "558 16 110 \n", "560 120 28 \n", "562 20 8 \n", "564 22 126 \n", "566 16 110 \n", "568 92 18 \n", "570 16 82 \n", "572 20 62 \n", "574 28 34 \n", "576 20 14 \n", "578 22 112 \n", "580 16 96 \n", "582 120 14 \n", "584 28 102 \n", "586 20 82 \n", "588 20 62 \n", "590 28 34 \n", "599 20 14 \n", "601 20 114 " ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "most_recent_trace = pd.DataFrame.from_dict(profiler.current_invocation_instruction_data, orient='index')\n", "most_recent_trace.index.name = 'Instruction'\n", "most_recent_trace" ] }, { "cell_type": "code", "execution_count": 10, "id": "10a09516", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset>\n",
       "Dimensions:             (Instruction: 33)\n",
       "Coordinates:\n",
       "  * Instruction         (Instruction) int64 514 516 518 520 ... 588 590 599 601\n",
       "Data variables:\n",
       "    timeslice_on_entry  (Instruction) int64 62 46 26 120 92 ... 102 82 62 34 14\n",
       "    stall_in_vcpu       (Instruction) int64 0 0 26 0 0 0 0 ... 96 14 0 0 0 0 14\n",
       "    in_display_loop     (Instruction) int64 0 0 652 0 0 0 0 ... 66 70 0 0 0 0 66\n",
       "    execution_time      (Instruction) int64 16 20 28 28 16 28 ... 20 20 28 20 20\n",
       "    timeslice_on_exit   (Instruction) int64 46 26 120 92 76 ... 82 62 34 14 114
" ], "text/plain": [ "\n", "Dimensions: (Instruction: 33)\n", "Coordinates:\n", " * Instruction (Instruction) int64 514 516 518 520 ... 588 590 599 601\n", "Data variables:\n", " timeslice_on_entry (Instruction) int64 62 46 26 120 92 ... 102 82 62 34 14\n", " stall_in_vcpu (Instruction) int64 0 0 26 0 0 0 0 ... 96 14 0 0 0 0 14\n", " in_display_loop (Instruction) int64 0 0 652 0 0 0 0 ... 66 70 0 0 0 0 66\n", " execution_time (Instruction) int64 16 20 28 28 16 28 ... 20 20 28 20 20\n", " timeslice_on_exit (Instruction) int64 46 26 120 92 76 ... 82 62 34 14 114" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "xr.Dataset.from_dataframe(most_recent_trace)" ] }, { "cell_type": "code", "execution_count": 11, "id": "5bf96137", "metadata": {}, "outputs": [], "source": [ "# I feel sure that there must be a better way!\n", "frames = [pd.DataFrame.from_dict(d, orient='index') for d in profiler.invocation_data]\n", "for f in frames: f.index.name = 'instruction'\n", "sets = [xr.Dataset.from_dataframe(f) for f in frames]\n", "del frames" ] }, { "cell_type": "code", "execution_count": 12, "id": "6fb60ae4", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset>\n",
       "Dimensions:             (instruction: 43, invocation: 20000)\n",
       "Coordinates:\n",
       "  * instruction         (instruction) int64 514 516 518 520 ... 595 597 599 601\n",
       "Dimensions without coordinates: invocation\n",
       "Data variables:\n",
       "    timeslice_on_entry  (invocation, instruction) float64 14.0 132.0 ... 14.0\n",
       "    stall_in_vcpu       (invocation, instruction) float64 14.0 0.0 ... 0.0 14.0\n",
       "    in_display_loop     (invocation, instruction) float64 652.0 0.0 ... 0.0 66.0\n",
       "    execution_time      (invocation, instruction) float64 16.0 20.0 ... 20.0\n",
       "    timeslice_on_exit   (invocation, instruction) float64 132.0 112.0 ... 114.0\n",
       "    total_time          (invocation, instruction) float64 682.0 20.0 ... 100.0
" ], "text/plain": [ "\n", "Dimensions: (instruction: 43, invocation: 20000)\n", "Coordinates:\n", " * instruction (instruction) int64 514 516 518 520 ... 595 597 599 601\n", "Dimensions without coordinates: invocation\n", "Data variables:\n", " timeslice_on_entry (invocation, instruction) float64 14.0 132.0 ... 14.0\n", " stall_in_vcpu (invocation, instruction) float64 14.0 0.0 ... 0.0 14.0\n", " in_display_loop (invocation, instruction) float64 652.0 0.0 ... 0.0 66.0\n", " execution_time (invocation, instruction) float64 16.0 20.0 ... 20.0\n", " timeslice_on_exit (invocation, instruction) float64 132.0 112.0 ... 114.0\n", " total_time (invocation, instruction) float64 682.0 20.0 ... 100.0" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "invocation_data = xr.concat(sets, dim='invocation')\n", "del sets\n", "invocation_data['total_time'] = sum(invocation_data[metric] for metric in ['stall_in_vcpu', 'in_display_loop', 'execution_time'])\n", "invocation_data" ] }, { "cell_type": "code", "execution_count": 13, "id": "c751526e", "metadata": {}, "outputs": [], "source": [ "def show_distribution(variable, *markers, **kwargs):\n", " \"\"\"Takes a variable, and returns a series of figures\n", " \n", " If markers are provided, they must also be a series.\n", " \"\"\"\n", " def plot(instruction):\n", " fig, ax = plt.subplots(1, 1, figsize=(2, 0.5))\n", " for k,v in ax.spines.items():\n", " v.set_visible(False)\n", " ax.set_xticks([])\n", " ax.set_yticks([])\n", "\n", " invocation_data.sel(instruction=instruction)[variable].plot.hist(ax=ax, **kwargs)\n", " for marker in markers:\n", " ax.axvline(x=marker[instruction], c='red')\n", " img = BytesIO()\n", " plt.savefig(img)\n", " img.seek(0)\n", " plt.close()\n", " return ''.format(base64.b64encode(img.read()).decode())\n", "\n", " return invocation_data.coords['instruction'].to_series().map(plot)" ] }, { "cell_type": "code", "execution_count": 14, "id": "088404a0", "metadata": {}, "outputs": [], "source": [ "cols = pd.MultiIndex.from_product([['execution_time', 'total_time'], ['min', 'max', 'mean', 'distribution']])\n", "stats = pd.DataFrame(columns=cols)\n", "for var, metric in cols:\n", " if metric == 'distribution':\n", " stats[var, metric] = show_distribution(var, stats[var, 'mean'])\n", " continue\n", " data = getattr(invocation_data[var], metric)('invocation')\n", " if metric != 'mean':\n", " data = data.astype('uint')\n", " stats[var, metric] = data.to_series()\n", "pd.options.display.float_format = '{:,.1f}'.format\n", "pd.set_option('display.max_colwidth', None)" ] }, { "cell_type": "code", "execution_count": 15, "id": "4e0be60c", "metadata": {}, "outputs": [], "source": [ "def disassemble(symbols, address):\n", " # Little vCPU disassembler copied from gt1dump.py\n", " \"\"\"Return the string disassembly of the given address\"\"\"\n", " # Need the reverse mapping\n", " symbols = {v: k for k, v in symbols.items()}\n", " next_vpc = address\n", " opcode = RAM[next_vpc]\n", " # If we don't know a mnemonic, just use hex - no operands\n", " mnemonic, number_of_operands = _OPCODES.get(opcode, (f\"${opcode:02x}\", 0))\n", " asm_parts = [mnemonic]\n", " operands = bytearray(RAM[next_vpc + 1 : next_vpc + 1 + number_of_operands])\n", " while operands:\n", " # Poor man's switch statement\n", " if mnemonic in _ZP_MODE_OPCODES:\n", " operand = operands.pop(0)\n", " decoding = symbols.get(operand, '') or _ZERO_PAGE_SYMBOLS.get(operand, '') or f\"${operand:02x}\"\n", " asm_parts.append(decoding)\n", " continue\n", " if mnemonic == \"Bcc\":\n", " operand = operands.pop(0)\n", " if operand in _BCC_CODES:\n", " asm_parts = [f\"B{_BCC_CODES[operand]}\"]\n", " # Fall through\n", " if mnemonic in {\"Bcc\", \"BRA\", \"DEF\"}:\n", " # Next operand is a target within a page\n", " operand = operands.pop(0)\n", " target = next_vpc & 0xFF00 | (operand + 2) & 0xFF\n", " asm_parts.append(f\"${target:04x}\")\n", " continue\n", " if mnemonic == \"SYS\":\n", " operand = operands.pop(0)\n", " if operand != 128:\n", " max_cycles = 28 - 2 * ((operand ^ 128) - 128)\n", " asm_parts.append(str(max_cycles))\n", " else:\n", " asm_parts = [\"HALT\"]\n", " continue\n", " # Else...\n", " # Treat any remaining bytes as a single operand\n", " operand = int.from_bytes(operands, \"little\", signed=False)\n", " asm_parts.append(f\"${operand:02x}\" if len(operands) == 1 else f\"${operand:04x}\")\n", " break\n", " return f\"{address:04x} {bytes(RAM[next_vpc : next_vpc + 1 + number_of_operands]).hex()} {' '.join(asm_parts)}\"\n", "\n", "\n", "_OPCODES = {\n", " 0x11: (\"LDWI\", 2),\n", " 0x1A: (\"LD\", 1),\n", " 0x1F: (\"CMPHS\", 1),\n", " 0x21: (\"LDW\", 1),\n", " 0x2B: (\"STW\", 1),\n", " 0x35: (\"Bcc\", 2),\n", " 0x59: (\"LDI\", 1),\n", " 0x5E: (\"ST\", 1),\n", " 0x63: (\"POP\", 0),\n", " 0x75: (\"PUSH\", 0),\n", " 0x7F: (\"LUP\", 1),\n", " 0x82: (\"ANDI\", 1),\n", " 0x85: (\"CALLI\", 2),\n", " 0x88: (\"ORI\", 1),\n", " 0x8C: (\"XORI\", 1),\n", " 0x90: (\"BRA\", 1),\n", " 0x93: (\"INC\", 1),\n", " 0x97: (\"CMPHU\", 1),\n", " 0x99: (\"ADDW\", 1),\n", " 0xAD: (\"PEEK\", 0),\n", " 0xB4: (\"SYS\", 1),\n", " 0xB8: (\"SUBW\", 1),\n", " 0xCD: (\"DEF\", 1),\n", " 0xCF: (\"CALL\", 1),\n", " 0xDF: (\"ALLOC\", 1),\n", " 0xE3: (\"ADDI\", 1),\n", " 0xE6: (\"SUBI\", 1),\n", " 0xE9: (\"LSLW\", 0),\n", " 0xEC: (\"STLW\", 1),\n", " 0xEE: (\"LDLW\", 1),\n", " 0xF0: (\"POKE\", 1),\n", " 0xF3: (\"DOKE\", 1),\n", " 0xF6: (\"DEEK\", 0),\n", " 0xF8: (\"ANDW\", 1),\n", " 0xFA: (\"ORW\", 1),\n", " 0xFC: (\"XORW\", 1),\n", " 0xFF: (\"RET\", 0),\n", "}\n", "\n", "_BCC_CODES = {\n", " 0x3F: \"EQ\",\n", " 0x4D: \"GT\",\n", " 0x50: \"LT\",\n", " 0x53: \"GE\",\n", " 0x56: \"LE\",\n", " 0x72: \"NE\",\n", "}\n", "\n", "_ZERO_PAGE_SYMBOLS = {\n", " 0x00: \"zeroConst\",\n", " 0x01: \"memSize\",\n", " 0x06: \"entropy\",\n", " 0x09: \"videoY\",\n", " 0x0E: \"frameCount\",\n", " 0x0F: \"serialRaw\",\n", " 0x11: \"buttonState\",\n", " 0x14: \"xoutMask\",\n", " 0x16: \"vPC\",\n", " 0x17: \"vPC+1\",\n", " 0x18: \"vAC\",\n", " 0x19: \"vAC+1\",\n", " 0x1A: \"vLR\",\n", " 0x1B: \"vLR+1\",\n", " 0x1C: \"vSP\",\n", " 0x21: \"romType\",\n", " 0x22: \"sysFn\",\n", " 0x23: \"sysFn+1\",\n", " 0x24: \"sysArgs+0\",\n", " 0x25: \"sysArgs+1\",\n", " 0x26: \"sysArgs+2\",\n", " 0x27: \"sysArgs+3\",\n", " 0x28: \"sysArgs+4\",\n", " 0x29: \"sysArgs+5\",\n", " 0x2A: \"sysArgs+6\",\n", " 0x2B: \"sysArgs+7\",\n", " 0x2C: \"soundTimer\",\n", " 0x2E: \"ledState_v2\",\n", " 0x2F: \"ledTempo\",\n", " 0x80: \"oneConst\",\n", "}\n", "\n", "# Opcodes that address page zero\n", "_ZP_MODE_OPCODES = {\n", " \"LD\",\n", " \"LDW\",\n", " \"STW\",\n", " \"ST\",\n", " \"INC\",\n", " \"ADDW\",\n", " \"SUBW\",\n", " \"CALL\",\n", " \"POKE\",\n", " \"DOKE\",\n", " \"ANDW\",\n", " \"ORW\",\n", " \"XORW\",\n", " \"CMPHS\",\n", " \"CMPHU\",\n", "}\n" ] }, { "cell_type": "code", "execution_count": 16, "id": "dd1c3202", "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
execution_timetotal_time
minmaxmeandistributionminmaxmeandistribution
instruction
0202 5900 LDI $00161616.01669525.7
0204 2b30 STW sign202020.02069825.3
0206 b832 SUBW A282828.028711146.1
0208 35560f BLE $0211282828.028703290.1
020b 2b32 STW A202020.02069366.2
020d 5901 LDI $01161616.016678167.9
020f 2b30 STW sign202020.02069327.1
0211 5900 LDI $00161616.01669733.4
0213 b834 SUBW B282828.028700136.7
0215 35561e BLE $0220282828.028713117.5
0218 2b34 STW B202020.02069379.8
021a 2130 LDW sign202020.020693167.2
021c 8c01 XORI $01141414.01468260.5
021e 2b30 STW sign202020.02070324.8
0220 1a32 LD A222222.022694131.6
0222 5e24 ST sysArgs+0161616.016703252.0
0224 1a34 LD B222222.02269527.8
0226 5e25 ST sysArgs+1161616.01669354.6
0228 b4d2 SYS 12092120101.2921087660.7
022a 2b29 STW sysArgs+5202020.02068442.1
022c 1a35 LD $35222222.022694206.2
022e 5e25 ST sysArgs+1161616.016682345.2
0230 b4d2 SYS 1209212099.4921045357.6
0232 2b36 STW C202020.02011824.5
0234 1a33 LD $33222222.022694502.5
0236 5e24 ST sysArgs+0161616.01668272.6
0238 b4dd SYS 98929292.092819128.8
023a 5e2b ST sysArgs+7161616.016689484.0
023c 212a LDW sysArgs+6202020.02069696.1
023e 9936 ADDW C282828.02870031.0
0240 2b36 STW C202020.0202020.0
0242 1a34 LD B222222.02211522.6
0244 5e25 ST sysArgs+1161616.01669119.3
0246 b4d2 SYS 12092120100.992997655.5
0248 9936 ADDW C282828.02869234.3
024a 2b36 STW C202020.020684194.1
024c 2130 LDW sign202020.020680370.9
024e 353f55 BEQ $0257282828.0282828.0
0251 5900 LDI $00161616.01668518.0
0253 b836 SUBW C282828.02870942.0
0255 9057 BRA $0259141414.01467423.0
0257 2136 LDW C202020.02068921.0
0259 ff RET202020.02069752.9
" ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "decoding = invocation_data.coords['instruction'].to_series().map(lambda a: disassemble(my_symbols, a))\n", "stats.index = decoding\n", "pd.set_option('display.max_colwidth', None)\n", "HTML(stats.to_html(escape=False))" ] }, { "cell_type": "code", "execution_count": 17, "id": "87c1e89d", "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
timeslice_on_entrystall_in_vcpuin_display_loopexecution_timetimeslice_on_exit
minmaxmeandistributionminmaxmeandistributionminmaxmeandistributionminmaxmeandistributionminmaxmeandistribution
instruction
0202 5900 LDI $00212277.00241.006618.8161616.01213268.9
0204 2b30 STW sign1213268.90260.506614.8202020.0812853.3
0206 b832 SUBW A812853.30265.20661112.9282828.0812053.4
0208 35560f BLE $0211812053.40245.60661256.5282828.01012080.1
020b 2b32 STW A1012073.00161.1066145.1202020.01012865.4
020d 5901 LDI $011012865.40223.60652148.3161616.01213287.2
020f 2b30 STW sign1213287.20220.906616.2202020.01412872.3
0211 5900 LDI $001012879.80221.2066116.2161616.01413273.0
0213 b834 SUBW B1413273.00263.50652105.2282828.0212069.1
0215 35561e BLE $0220212069.10262.9066186.6282828.0012061.0
0218 2b34 STW B012069.40263.2066156.6202020.01012867.9
021a 2130 LDW sign1012867.90225.10661142.1202020.0812879.9
021c 8c01 XORI $01812879.90222.1065244.4141414.01613482.6
021e 2b30 STW sign1613482.60240.206614.6202020.01612864.0
0220 1a32 LD A012858.60263.20661106.4222222.0612662.8
0222 5e24 ST sysArgs+0612662.80269.00661227.0161616.01213291.3
0224 1a34 LD B1213291.30261.206614.5222222.01012675.6
0226 5e25 ST sysArgs+11012675.60201.6066137.1161616.01613271.9
0228 b4d2 SYS 1201613271.9021866.30749493.292120101.2105642.7
022a 2b29 STW sysArgs+5105642.70141.2065220.9202020.0812834.4
022c 1a35 LD $35812834.40225.50652178.7222222.01412664.8
022e 5e25 ST sysArgs+11412664.80147.00652322.2161616.040132115.3
0230 b4d2 SYS 12040132115.3020851.00749207.29212099.4105637.5
0232 2b36 STW C105637.50140.70883.8202020.0811424.1
0234 1a33 LD $33811424.102214.80652465.7222222.014126111.8
0236 5e24 ST sysArgs+014126111.80141.2065255.4161616.046132107.2
0238 b4dd SYS 9846132107.209619.3066117.5929292.0125624.7
023a 5e2b ST sysArgs+7125624.701812.60661455.3161616.02213299.9
023c 212a LDW sysArgs+62213299.90267.2065269.0202020.020128112.7
023e 9936 ADDW C20128112.70200.106522.9282828.03412085.3
0240 2b36 STW C3412085.3000.0000.0202020.01410065.3
0242 1a34 LD B1410065.30140.10790.5222222.0811244.0
0244 5e25 ST sysArgs+1811244.00140.106613.2161616.02413228.8
0246 b4d2 SYS 1202413228.8014029.10749525.692120100.9105643.8
0248 9936 ADDW C105643.80140.906525.4282828.0012024.1
024a 2b36 STW C012024.10141.90652172.2202020.0812858.4
024c 2130 LDW sign812858.4084.30652346.7202020.036128113.1
024e 353f55 BEQ $025736128113.1000.0000.0282828.0810085.1
0251 5900 LDI $00810076.90220.006612.0161616.01413261.4
0253 b836 SUBW C1413261.40223.2066110.8282828.0612050.2
0255 9057 BRA $0259612050.20221.306527.8141414.02213443.4
0257 2136 LDW C810085.7080.006611.0202020.01012865.9
0259 ff RET1013464.40221.9066131.0202020.01012856.3
" ], "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cols = pd.MultiIndex.from_product([_PER_INSTRUCTION_DATA, ['min', 'max', 'mean', 'distribution']])\n", "detailed = pd.DataFrame(columns=cols)\n", "for var, metric in cols:\n", " if metric == 'distribution':\n", " detailed[var, metric] = show_distribution(var, detailed[var, 'mean'], bins=32)\n", " continue\n", " data = getattr(invocation_data[var], metric)('invocation')\n", " if metric != 'mean':\n", " data = data.astype('uint')\n", " detailed[var, metric] = data.to_series()\n", "detailed.index = decoding\n", "HTML(detailed.to_html(escape=False))" ] }, { "cell_type": "code", "execution_count": 18, "id": "291e662a", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
invocations
instruction
51420000
51620000
51820000
52020000
5238552
5258552
5278552
52920000
53120000
53320000
5368787
5388787
5408787
5428787
54420000
54620000
54820000
55020000
55220000
55420000
55620000
55820000
56020000
56220000
56420000
56620000
56820000
57020000
57220000
57420000
57620000
57820000
58020000
58220000
58420000
58620000
58820000
59020000
5931391
5951391
5971391
59918609
60120000
\n", "
" ], "text/plain": [ " invocations\n", "instruction \n", "514 20000\n", "516 20000\n", "518 20000\n", "520 20000\n", "523 8552\n", "525 8552\n", "527 8552\n", "529 20000\n", "531 20000\n", "533 20000\n", "536 8787\n", "538 8787\n", "540 8787\n", "542 8787\n", "544 20000\n", "546 20000\n", "548 20000\n", "550 20000\n", "552 20000\n", "554 20000\n", "556 20000\n", "558 20000\n", "560 20000\n", "562 20000\n", "564 20000\n", "566 20000\n", "568 20000\n", "570 20000\n", "572 20000\n", "574 20000\n", "576 20000\n", "578 20000\n", "580 20000\n", "582 20000\n", "584 20000\n", "586 20000\n", "588 20000\n", "590 20000\n", "593 1391\n", "595 1391\n", "597 1391\n", "599 18609\n", "601 20000" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "invocation_data['execution_time'].count('invocation').rename('invocations').to_dataframe()" ] }, { "cell_type": "code", "execution_count": 19, "id": "3f9ae6a6", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
execution_timestall_in_vcpuin_display_looptotal_time
Percentage
018.24.677.3100.0
\n", "
" ], "text/plain": [ " execution_time stall_in_vcpu in_display_loop total_time\n", "Percentage \n", "0 18.2 4.6 77.3 100.0" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "totals = invocation_data.sum('invocation').sum('instruction')[['execution_time', 'stall_in_vcpu', 'in_display_loop', 'total_time']]\n", "percentages = totals / totals['total_time'] * 100\n", "percentages.expand_dims('Percentage').to_dataframe()" ] }, { "cell_type": "code", "execution_count": null, "id": "907d80bd", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "PyPy3 (Multiply)", "language": "python", "name": "pypy3-multiply" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10" } }, "nbformat": 4, "nbformat_minor": 5 }