<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>fundamental code</title>
    <description>Math Music And More
</description>
    <link>http://log.fundamental-code.com/</link>
    <atom:link href="http://log.fundamental-code.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Fri, 03 May 2024 21:29:14 -0400</pubDate>
    <lastBuildDate>Fri, 03 May 2024 21:29:14 -0400</lastBuildDate>
    <generator>Jekyll v4.2.0</generator>
    
      <item>
        <title>The DIY Mark I CPU</title>
        <description>&lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Every once in a while I get the urge to reminisce about a past project. So,
today let&amp;#8217;s look back on one of my favorite projects from my undergrad computer
engineering degree, or as I like to call it:&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;the-time-when-i-built-a-custom-cpu-because-writing-software-was-easier-than-designing-hardware&quot;&gt;The Time When I Built a Custom CPU Because Writing Software Was Easier Than Designing Hardware&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;One of my lab courses focused on building a sequence of group projects with
ever increasing complexity.
Most of them ended up being games with a focus on an FPGA development board,
a serial connection, and some custom software running on a desktop computer.
The individual projects that have stuck around in my mind are:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;A GAL (Generic Array Logic) and discrete component based traffic light
control system with a pedestrian button.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;An etch a sketch application where the FPGA acted as a hardware controller
and the desktop computer translated move operations and whether the cursor was
depressed into a displayed image&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A game of hangman where the hardware system read key events from a PS1
keyboard and then submitted full words as guesses to the computer for updating
the display.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A signal capture tool using an ADC/DAC set of chips with an on desktop
visualizer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A student selected project, which for my team was a two player game of pong
displayed on an analog oscilloscope.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2024-04-gal-traffic-light.jpg&quot; alt=&quot;2024 04 gal traffic light&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The whole sequence of projects started out with a GAL+discrete logic based
assignment.
We were tasked with building up a system for a standard 4 way intersection with
an set of pedestrian crossings and associated pedestrian crossing request
button.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2024-04-traffic.png&quot; alt=&quot;2024 04 traffic&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We had lookup tables in the GAL, counters, timers, logic to decode our state
into which lights were on, binary to 7 segment decoder chips, etc.
It was a lot.
As you might be able to see what we might have needed the most was some more
rigor in terms of our wiring job, but we managed to complete the task.
The project was a combination of loosely planning things and organically
patching any mistakes we had made while watching the system through a logic
squid.
It was remarkable how much physical devices slowed down development.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The subsequent projects took us one step back from 80s style of physically
building out logic into the era of defining our systems in a hardware
description language, namely VHDL.
This sped things up considerably, though the tooling available to students was
subpar at the time (or at least that was the case at my university),
so I wanted to make another technological leap and move into software.
That required us to have a CPU of some sort and the assignments were always
about turning in the hardware description of a system, so it couldn&amp;#8217;t be
imported from an external project like OpenCores.
I knew from my tinkering in open source software that the later projects would
be either take less time or be more fun with a basic CPU that could be reused
from project to project, so I set off and made one.
Certainly it was creating something bespoke with no online resources, but at the
time resources for VHDL were *sparse*.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The classes focused around state machines, so how much harder could it be to
build up a programmable state machine?
A computer or in our case a very very terrible minimal computer was born.
The CPU itself was copied between projects with near zero changes and just
enough custom peripherals were created per assignment to get the system over the
finish line.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;system-overview&quot;&gt;System Overview&lt;/h3&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2024-04-DE1.jpg&quot; alt=&quot;2024 04 DE1&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The DE1 development board we worked with has a bunch of LEDs, some switches, a
few momentary buttons, some RAM, and a few electrical connections to the rest of
the world in the form of a serial port, a PS2 keyboard connection, and some
general purpose IO pins.
There are some other bells and whistles, but they aren&amp;#8217;t particularly relevant.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The custom Mark 1 CPU was built to handle the orchestration between these
peripherals and was as simple as you could reasonably get.
At the time I was often tinkering around with some of the AVR processors and I
enjoyed dealing with the simplicity of an 8 bit system, so I made the Mark 1 a
fully 8 bit system.
8 bits of addressable memory, 8 bits of addressable program ROM, and only four
8-bit or less registers.
By the last project the instruction set had grown to 22 opcodes and it was
running at a blazing fast 50MHz.
It was certainly stripped down with no interrupts, no relative jumps, no
pipelines, and no variable cycle instructions, but it worked well enough for the
course.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;architecture&quot;&gt;Architecture&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As mentioned before, the CPU was thoroughly an 8-bit system,
8-bit addressable memory, 8-bit program
ROMS, 8-bit operands, and four 8-bit or less registers.
Those registers were:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The Status register (SR)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The general purpose register (REG)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The indexing register (IDX)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The program counter (PC)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;SR stored system flags such as the is-equal flag, the is-zero flag, and other
application specific flags.
REG is used to for general loading from memory, arithmetic operations,
comparisons, and temporary storage.
IDX is used for stack management, indirect memory access, and iteration.
PC is used to track the current position in the system ROM, which determines the
current instruction; In other systems this is referred to as an Instruction
Pointer (IP).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Our instruction set can be summarized below:&lt;/p&gt;
&lt;/div&gt;
&lt;table class=&quot;tableblock frame-all grid-all stripes-even fit-content stretch&quot;&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Memonic&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Arg.&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;PC&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;SR&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;REG&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;IDX&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;ALU&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Bus&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Cycles&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;read&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Ar&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;$REG := (Ar)&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;load&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;V&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;$REG := V&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;send&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Ar&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;(Ar) := $REG&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;test&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;V&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;\$SR &amp;#8656; $REG==V&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;jsrr&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&amp;#8230;&amp;#8203;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;\$PC  := $REG&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;goto&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Ap&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&amp;#8230;&amp;#8203;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;\$PC := Ap&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;brnz&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Ap&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;$PC := Ap&lt;/strong&gt; if $REG!=0&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;brzz&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Ap&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;$PC := Ap&lt;/strong&gt; if $REG==0&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;breq&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Ap&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;$PC := Ap&lt;/strong&gt; if $SR.equal is true&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;brc0&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Ap&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;$PC := Ap&lt;/strong&gt; if control 0 is true&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;brc1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Ap&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;$PC := Ap&lt;/strong&gt; if control 1 is true&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;addd&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;V&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i.F&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;\$REG := $REG + V&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;subx&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;V&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i.F&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;\$REG := $REG - V&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;spsh&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;V&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;ii.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;($IDX++) := V&lt;/strong&gt; push V to stack&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;rpsh&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;ii.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;(\$IDX++) := $REG&lt;/strong&gt; push $REG to stack&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;spop&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;id.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;$RED := (--$IDX)&lt;/strong&gt; pop value to $REG&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;lspt&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;V&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;\$IDX := V&lt;/strong&gt; load stack pointer&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;sidx&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;V&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;\$IDX := V&lt;/strong&gt; set index&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;iidx&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;ii.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;\$IDX := $IDX+1&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;lidx&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;\$REG := ($IDX)&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;swap&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;swap(\$REG,$IDX)&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;trap&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;W&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&amp;#8230;&amp;#8203;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Reset system&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;noop&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;i..&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Do nothing&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;R(ead), W(rite), .(nothing), V(alue), Ar(Address/RAM), Ap(Address/Program), ALU
(PC-IDX-REG) i(ncrement ALU), d(ecrement ALU), F(ull ALU)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In total these 22 opcodes were in the final VHDL version of the CPU that I was
able to locate (technically 23, but &lt;code&gt;lspt&lt;/code&gt; and &lt;code&gt;sidx&lt;/code&gt; are identical).
No opcode encoding work was done, that was left to the VHDL generation tools,
but opcodes could easily be 8 bits to fit with the overall theme of the project.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;One challenge of working with this instruction set was that relative jumps
are not in the instruction set which means that a list of destination addresses
needed to be maintained.
Most code modifications were painful if it shifted code by even one address, so
the Mark I CPU even has an assembler, but I&amp;#8217;ll get to that a bit later.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;peripherals&quot;&gt;Peripherals&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You might notice that the CPU only interacts with registers, the 256 bytes of
memory, and a few control lines with those branch instructions.
So how does it work with the rest of the IO world?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Memory mapped peripherals.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Similar to embedded microcontrollers if the CPU writes to a given &apos;magic&apos;
address it is going to be writing or reading values in a peripheral that&amp;#8217;s wired
onto the main bus.
Heck, even memory is a peripheral in our case.
For most of the projects this CPU was used in we were required to use the SRAM
chip on the DE1 board.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Since I&amp;#8217;ve lost some of the code used with the Mark I based CPU projects I don&amp;#8217;t
have an exhaustive list, but I can find evidence of memory mapped peripherals
for:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SRAM : General purpose memory&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A debug interface : manually Stepping the CPU and visualizing the address/data
lines&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A timer : for accurately and regularly tending to tasks. This peripheral had
to be polled since no interrupts exist in this CPU&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A UART : for communicating to computers over a serial link&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Beeper : for making sounds when a player has done an action in games&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A vector graphics video driver with selectable VROM banks : For rendering
graphics on X/Y mode oscilloscope outputs&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A PS2 keyboard driver : for typing in commands&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A character LCD driver : for displaying what uses have typed&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A seven segment display driver : typically for visualizing debug information&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;User input buttons : for binary user inputs or for stepping through the code
at low speeds (It&amp;#8217;s pretty hard to visualize things by eye at 50 MHz)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If I attempt to build another CPU in the future I expect a huge portion of the
time will focus on the debug interface.
I personally find them delightful.
For a particularly good set of examples take a look at the Magic processor&amp;#8217;s
front panel or the currently available PDP-11 replica front panels by
Obsolescence Guaranteed.
In fact the user interface component is a delightful space to explore for
complex systems whether that&amp;#8217;s processors, synths, control systems, or some
other complex system that needs to precisely communicate information to a
skilled user.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;assembler-examples&quot;&gt;Assembler &amp;amp; Examples&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As mentioned before, the processor does not have relative jumps which makes
program modifications tedious if we don&amp;#8217;t have an assembler.
The assembler itself is pretty trivial with most of the point being tracking the
addresses of assembled instructions.
In fact almost all of the meaningful bits of it can be seen in these yacc/lex
snippets:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;asm.y The primary grammar of the assembler&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;make&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000FF&quot;&gt;program&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;:&lt;/span&gt;
       program statement &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;
       |
       ;
&lt;span style=&quot;color: #0000FF&quot;&gt;statement&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;:&lt;/span&gt;
         express
         | label express
         | label
         | directive
         |
         ;
&lt;span style=&quot;color: #0000FF&quot;&gt;directive&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;:&lt;/span&gt;
         EQU SYMBOL NUMBER &lt;span style=&quot;color: #666666&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$2&lt;/span&gt;-&amp;gt;val&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$3&lt;/span&gt;;&lt;span style=&quot;color: #666666&quot;&gt;}&lt;/span&gt;
         | START &lt;span style=&quot;color: #666666&quot;&gt;{&lt;/span&gt;pass++;&lt;span style=&quot;color: #19177C&quot;&gt;pc&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt;;&lt;span style=&quot;color: #666666&quot;&gt;}&lt;/span&gt;
         | SRC SYMBOL &lt;span style=&quot;color: #666666&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;pass&amp;gt;1&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt; printf&lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;--%s\n&amp;quot;&lt;/span&gt;,&lt;span style=&quot;color: #19177C&quot;&gt;$2&lt;/span&gt;-&amp;gt;name&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt;;&lt;span style=&quot;color: #666666&quot;&gt;}&lt;/span&gt;
         ;

&lt;span style=&quot;color: #0000FF&quot;&gt;express&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;:&lt;/span&gt;
       OPCODE          &lt;span style=&quot;color: #666666&quot;&gt;{&lt;/span&gt;line&lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$1&lt;/span&gt;, 0x00&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt;;&lt;span style=&quot;color: #666666&quot;&gt;}&lt;/span&gt;
       | OPCODE SYMBOL &lt;span style=&quot;color: #666666&quot;&gt;{&lt;/span&gt;line&lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$1&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;$2&lt;/span&gt;-&amp;gt;val&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt;;&lt;span style=&quot;color: #666666&quot;&gt;}&lt;/span&gt;
       | OPCODE NUMBER &lt;span style=&quot;color: #666666&quot;&gt;{&lt;/span&gt;line&lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$1&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;$2&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt;;&lt;span style=&quot;color: #666666&quot;&gt;}&lt;/span&gt;
       ;
&lt;span style=&quot;color: #0000FF&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;:&lt;/span&gt;
     SYMBOL &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;        &lt;span style=&quot;color: #666666&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$1&lt;/span&gt;-&amp;gt;val&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;pc;&lt;span style=&quot;color: #666666&quot;&gt;}&lt;/span&gt;
     ;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;asm.lex the tokenization of the assembler&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span&gt;&lt;/span&gt;;.&lt;span style=&quot;color: #666666&quot;&gt;*&lt;/span&gt;         &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;/*Ignore comments*/&lt;/span&gt;
[ ]&lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt;            &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;/*Ignore whitespace*/&lt;/span&gt;
iidx&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;read&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;test&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;swap&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;spop yylval.string&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;strdup(yytext); &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; OPCODE;
load&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;send&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;nopp&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;goto&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;subx yylval.string&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;strdup(yytext); &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; OPCODE;
rpsh&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;rpop&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;spsh&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;trap          yylval.string&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;strdup(yytext); &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; OPCODE;
addd&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;brc[&lt;span style=&quot;color: #666666&quot;&gt;0-2&lt;/span&gt;]&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;jsrr&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;breq&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;sidx yylval.string&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;strdup(yytext); &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; OPCODE;
brnz&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;brzz&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;lidx yylval.string&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;strdup(yytext); &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; OPCODE;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#[0-9a-fA-F]+   sscanf(yytext+1,&amp;quot;%X&amp;quot;,&amp;amp;yylval); return NUMBER;&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;%&lt;/span&gt;[&lt;span style=&quot;color: #666666&quot;&gt;0-9&lt;/span&gt;a&lt;span style=&quot;color: #666666&quot;&gt;-&lt;/span&gt;zA&lt;span style=&quot;color: #666666&quot;&gt;-&lt;/span&gt;Z]    yylval.number &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; (&lt;span style=&quot;color: #B00040&quot;&gt;char&lt;/span&gt;) yytext[&lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;];    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; NUMBER;
[_a&lt;span style=&quot;color: #666666&quot;&gt;-&lt;/span&gt;zA&lt;span style=&quot;color: #666666&quot;&gt;-&lt;/span&gt;Z]&lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt;      yylval.sym&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;intern(yytext);    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; SYMBOL;
&lt;span style=&quot;color: #666666&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;\&lt;/span&gt;.start        &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; START;
&lt;span style=&quot;color: #666666&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;\&lt;/span&gt;.equ          &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; EQU;
&lt;span style=&quot;color: #666666&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;\&lt;/span&gt;.src          &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; SRC;
&lt;span style=&quot;color: #666666&quot;&gt;:&lt;/span&gt;               &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;*&lt;/span&gt;yytext;
&lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;\&lt;/span&gt;n              &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;*&lt;/span&gt;yytext;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A program consists of a sequence of statements.
Those statements are either labels for code to jump to, opcodes with optional
arguments, definitions of constants, or definitions of functions which are
printed as comments in the generated code.
Easy enough for something as low level as an assembler, right?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So, what does a real program look like?
Well, let&amp;#8217;s look at a slightly modified assembly project.
Before looking at the code this is from the project where a collection of analog
values are read from an external chip, then transmitted over a serial connection to be displayed on a
PC.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To start off, let&amp;#8217;s look at some constants:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;nasm&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;Define constants&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.equ&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;UART_TX&lt;/span&gt;     &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;02&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.equ&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;LEDS&lt;/span&gt;        &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;01&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.equ&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;ADC&lt;/span&gt;         &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;06&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.equ&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;STACKP&lt;/span&gt;      &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;21&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.equ&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;STACK_H&lt;/span&gt;     &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;F0&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.equ&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;BINTOASCII&lt;/span&gt;  &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;08&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.equ&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;ASCII_H&lt;/span&gt;     &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;09&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.equ&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;ASCII_L&lt;/span&gt;     &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;08&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.equ&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;TMP_SEND&lt;/span&gt;    &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;A2&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;brc0 is uart ready send&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In this program the CPU has a few system peripherals:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;A set of on board LEDs to display running values of our input memory mapped
at 0x01 (write only)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The serial link to the computer (UART) memory mapped to address 0x02
(write only)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The analog to digital chip mapped at 0x06 (read only)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A binary to ascii-hex conversion ROM mapped at 0x08 (input) and 0x08..0x09
(output)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In addition the stack that is used to store data which is sent to the PC is
0x21..0xF0, which should correspond to 103 8 bit values (in hex) and a null
terminator.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In addition, there is a set of comments that indicate that the UART is connected
to the CPU&amp;#8217;s control line 0 to signal when data can be sent.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;nasm&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.src&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;INIT_ROUTINE&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;init:&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;sidx&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;STACKP&lt;/span&gt;     &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;config stack&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;spsh&lt;/span&gt; &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;D&lt;/span&gt;        &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;&amp;#39;M&amp;#39;&lt;/span&gt;

&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.src&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;MAIN_ROUTINE&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;main:&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;goto&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;inputs&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;in_ret:&lt;/span&gt;     &lt;span style=&quot;color: #0000FF&quot;&gt;goto&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;outputs&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;out_ret:&lt;/span&gt;    &lt;span style=&quot;color: #0000FF&quot;&gt;goto&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;delay&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;del_ret:&lt;/span&gt;    &lt;span style=&quot;color: #0000FF&quot;&gt;goto&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;main&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The beginning of the program initializes the array/stack which is used to store
data which will be transmitted and then it establishes the main program flow.
inputs are collected, the input is output to the computer, the system waits, and
then it repeats the process.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;nasm&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.src&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;INPUT_ROUTINE&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;inputs:&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;read&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;ADC&lt;/span&gt;        &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;Get analog value&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;nopp&lt;/span&gt;

            &lt;span style=&quot;color: #0000FF&quot;&gt;send&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;BINTOASCII&lt;/span&gt; &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;Convert to ascii&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;send&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;LEDS&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;read&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;ASCII_H&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;nopp&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;rpsh&lt;/span&gt;            &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;Push values onto stack (char*)&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;nopp&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;read&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;ASCII_L&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;nopp&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;rpsh&lt;/span&gt;

            &lt;span style=&quot;color: #0000FF&quot;&gt;swap&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;test&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;STACK_H&lt;/span&gt;    &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;Check for end of loop&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;swap&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;breq&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;send_data&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;send_ret:&lt;/span&gt;   &lt;span style=&quot;color: #0000FF&quot;&gt;goto&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;in_ret&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Ignore the no-operation instructions here, but as the comments indicate data is
read from the ADC peripheral.
The data is converted into two bytes of hex-ascii (e.g.  0xfa), then stored on the stack.
At the end we check to see if the stack pointer is at its maximal value with the
&lt;code&gt;test&lt;/code&gt; instruction and if it is at that value we go to the next stage, otherwise
we keep gathering more input.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;nasm&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.src&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;SEND_ROUTINE&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;send_data:&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;spsh&lt;/span&gt; &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;A&lt;/span&gt;        &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;Add new line&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;spsh&lt;/span&gt; &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;00&lt;/span&gt;        &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;Add null terminator&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;sidx&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;STACKP&lt;/span&gt;     &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;Set start of char*&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;send_loop:&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;lidx&lt;/span&gt;            &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;Read in next value&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;nopp&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;brzz&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;send_exit&lt;/span&gt;  &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;Check for null terminator&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;send&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;TMP_SEND&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;wait:&lt;/span&gt;       &lt;span style=&quot;color: #0000FF&quot;&gt;brc0&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;do_send&lt;/span&gt;
            &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;do something useful while waiting&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;read&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;ADC&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;nopp&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;send&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;LEDS&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;goto&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;wait&lt;/span&gt;

&lt;span style=&quot;color: #A0A000&quot;&gt;do_send:&lt;/span&gt;    &lt;span style=&quot;color: #0000FF&quot;&gt;read&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;TMP_SEND&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;nopp&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;send&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;UART_TX&lt;/span&gt;    &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;Transmit data&lt;/span&gt;

            &lt;span style=&quot;color: #0000FF&quot;&gt;iidx&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;goto&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;send_loop&lt;/span&gt;

&lt;span style=&quot;color: #A0A000&quot;&gt;send_exit:&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;sidx&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;STACKP&lt;/span&gt;      &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;reset stack&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;spsh&lt;/span&gt; &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;D&lt;/span&gt;         &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;&amp;#39;M&amp;#39;&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;goto&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;in_ret&lt;/span&gt;

&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.src&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;OUTPUT_ROUTINE&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;outputs:&lt;/span&gt;    &lt;span style=&quot;color: #0000FF&quot;&gt;goto&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;out_ret&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Now with output we&amp;#8217;re getting to point we have something more complex.
In the first 3 instructions we establish that we have a null terminated string
starting at the constant address STACKP.
We now want to send this string byte by byte to the UART.
This is done by the send_loop.
When a character is sent we have to wait for the UART to be ready for the next
byte at which point we stay in the wait loop until the control line 0 indicates
we can send the next character.
When we do send the data it is moved from the TMP_SEND address to the UART_TX
memory mapped device and we repeat the process until the full string has been
sent.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Rewritten in C this looks like:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;C&quot;&gt;&lt;span&gt;&lt;/span&gt;uint8_t *stack_pos;
volatile uint8_t *led;
volatile uint8_t *adc;
volatile uint8_t *uart;

void send_data(void)
{
    uint8_t chr;
    (*stack_pos++) = &amp;#39;\n&amp;#39;;
    (*stack_pos++) = &amp;#39;\0&amp;#39;;
    stack_pos = STACKP;

    while(1) {
        chr = *stack_pos++;
        if(chr == 0)
            break;
        while(uart_busy())
            *led = *adc;
        *uart = chr;
    }
    stack_pos = STACKP;
    (*stack_pos++) = &amp;#39;M&amp;#39;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;nasm&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #0000FF&quot;&gt;.src&lt;/span&gt;        &lt;span style=&quot;color: #19177C&quot;&gt;DELAY_ROUTINE&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;delay:&lt;/span&gt;      &lt;span style=&quot;color: #0000FF&quot;&gt;load&lt;/span&gt; &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;00&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;delay_loop:&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;addd&lt;/span&gt; &lt;span style=&quot;border: 1px solid #FF0000&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;FF&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;nopp&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;nopp&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;brnz&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;delay_loop&lt;/span&gt;
            &lt;span style=&quot;color: #0000FF&quot;&gt;goto&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;del_ret&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The delay routine is the last one it counts from 0 to 256 (more or less)
and we can calculate how long this should take to execute.
The processor runs at 50MHz with one instruction per cycle, one loop is 4
instructions (add+2x no-op+branch).
So, 256*4+1+1 (for the initial load and final goto), so roughly 20
micro-seconds.
Not much time at all.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;quirks&quot;&gt;Quirks&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The processor had its fair share of quirks and general limitations. While this
is by no means a comprehensive list a few that were pain points at the time:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It was a 50MHz, all actions on rising edge of clock, nothing on falling edge.
The speed was higher than was needed and the lack of falling edge operations
resulted in several quirks around reads and writes bleeding into a 2 cycle
instruction&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;No secondary register, so manually allocating the single register to various
tasks was fiddly&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;No function call/return opcodes, so subroutine calls are verbose operations
where the user had to save their variables before placing a return
address on the stack and then making
sure the called code ends with popping a value from the stack and
unconditionally jumping to the current register value&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Read is a multi-tick operation and multi-tick instructions do not exist, so no
op instructions were manually inserted&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Occasional bugs where on some revisions jumps would occur &lt;em&gt;before&lt;/em&gt; the
program counter was incremented.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;256 instructions really isn&amp;#8217;t a lot. For basic problems sure, that&amp;#8217;s loads and
when you can write arbitrary peripherals it&amp;#8217;s workable, but I did run out of
program space more than once in the development of the final project&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;looking-back&quot;&gt;Looking back&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It&amp;#8217;s pretty amazing looking back at the specs for the DE1 board. Those boards
are still sold, but an updated revision.
The newer revision is a heck of a lot more powerful than they used to be.
Reading the spec sheet of the individual FPGA on my board I&amp;#8217;ve got 18,752 logic
elements and the new FPGA simply specifies 77k logic elements which gives me the
sense that students aren&amp;#8217;t running into those situations where they&amp;#8217;ve exhausted
every single logic unit on one of these boards while doing classwork.
The newer board don&amp;#8217;t even need the effort of building a custom CPU since
they&amp;#8217;ve got a built in ARM core.
Heck, the ARM core has access to a full GB of RAM, which is remarkable compared
to the 8MB of SDRAM on my board and the 256 bytes of address space of the Mark I
CPU.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Mark I CPU worked, it did its job and while I haven&amp;#8217;t accomplished my
personal goal of making a CPU from raw transistors it got me a decent part
of the way there.
If I do go all the way to transistors I&amp;#8217;m guessing I&amp;#8217;ll go down to 4 bits or
have the pcb fab assemble the ocean of transistors.
Overall it&amp;#8217;s a fun space and simple instruction sets are really interesting.
I don&amp;#8217;t play around with them as much as I used to, but it is a delight to read
through ISRs like the z80 or AVR.
There&amp;#8217;s a beauty to them that is lost in the pragmatic full instruction sets you
see in x86 and arm.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So, I&amp;#8217;ll leave this article here for now. I may well get back to it and edit it
some more or extend it, but this has been sitting in my drafts folder long
enough that I should put it up on my website before it collects another layer of
dust.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Sat, 20 Apr 2024 00:00:00 -0400</pubDate>
        <link>http://log.fundamental-code.com/2024/04/20/custom-cpu.html</link>
        <guid isPermaLink="true">http://log.fundamental-code.com/2024/04/20/custom-cpu.html</guid>
        
        
      </item>
    
      <item>
        <title>System Profiling with Perfetto</title>
        <description>&lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Programs aren&amp;#8217;t perfect and that doesn&amp;#8217;t mean just bugs.
Quite often a program will accomplish it&amp;#8217;s goal, but not as quickly as both
developers and users would like.
Solving performance problems can be complicated, but it often starts at
identifying why a program is slow via profiling.
Profiling informs what a codebase is doing, how the work is being done,
in what order code is being executed, and quite often highlights the
hotspots where a few lines of code account for most of the time.
Programmers have a wide variety of tools for profiling nowadays, though like
most tools they do have trade-offs which create specializations.
The tools can vary considerably due to the execution environment, target
programming languages, and assumed root causes of a program being slow.
Note, I do have to say assumed root cause because until you can quantify the
behavior of a program you only have educated guesses.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;types-of-profilers&quot;&gt;Types of Profilers&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Profilers will quantify the question of &quot;How long does it take to do X?&quot;,
but the profilers don&amp;#8217;t need to be complex.
For instance I could sit down, look at a program and say
&quot;I think function &lt;code&gt;X()&lt;/code&gt; is taking longer than expected&quot;.
System timers could quantify how long a program takes to run with &lt;code&gt;time&lt;/code&gt; (e.g. a
unit test for &lt;code&gt;X()&lt;/code&gt;) or code can be modified to collect the runtime of &lt;code&gt;X()&lt;/code&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;/span&gt;void
some_function(void)
{
    struct timespec start, end;
    //Record the time before entering X()
    clock_gettime(CLOCK_MONOTONIC, &amp;amp;start);

    X();

    //Record the time after exiting X()
    clock_gettime(CLOCK_MONOTONIC, &amp;amp;end);

    printf(&amp;quot;X took %f ms\n&amp;quot;, get_timediff_ms(end, start));
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;At the end of the day how it takes to run a critical section of code is what
matters, though getting only a single time for a program is a very coarse metric.
It&amp;#8217;s possible that we can see what our target function &lt;code&gt;X()&lt;/code&gt; calls and then
annotate &lt;code&gt;Y()&lt;/code&gt;, &lt;code&gt;Z()&lt;/code&gt;, etc, though that is slow work and can produce hard to
understand output.
We don&amp;#8217;t need to add these timers ourselves though as automated tooling exists.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Sampling profilers like perf, gprof, or the-poor-man&amp;#8217;s-profiler automate our
work by periodically capturing a stacktrace of a program without manual
annotations.
Quite often sampling profilers focus on slower events (e.g. being IO bound)
and sequences of operations.
A major weakness from my experiences with sampling profilers is the tooling to
visualize the output of the collected traces is lackluster.
My opinions are very much colored by the types of application optimization
hurdles that I&amp;#8217;ve needed to fix in the past, so take my opinion with a grain of
salt.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;My favored type of profiler is the instrumenting profiler which involves
modifications to the program to generate information about the execution flow.
Out of all of the instrumenting profilers, valgrind is my go-to tool.
Valgrind automates the instrumentation needed to perform profiling,
to track memory allocations, and to detect several classes of memory faults
common in C and C++ programs.
Valgrind executes every instruction in a VM and thus can see the exact pathway
the program uses, but at a fairly high cost.
A program executing 20x slower under valgrind isn&amp;#8217;t unexpected, but that&amp;#8217;s the
price paid for convenient access to a program&amp;#8217;s behavior.
If you are working with compute bound single threaded tasks I can&amp;#8217;t recommend
kcachegrind&amp;#8217;s visualization of valgrind&amp;#8217;s output enough.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;system-profilers&quot;&gt;System Profilers&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So, why do we need anything more than the profilers already mentioned?
Well, a lot of the tools don&amp;#8217;t do a great job at representing performance issues
that occur across multiple threads, multiple programs, or are centered around
inconsistencies in resources external to an application (IO/drivers/etc).
A fair number of these problems are difficult to manage in the best of times
and they&amp;#8217;re becoming more common as system complexity increases with more
powerful hardware.
Sampling profilers can be used in some of these situations to generate traces,
though as I mentioned before the data visualization associated with the sampling
profilers is non-ideal to non-existent.
Although I love valgrind, the output of the profiling is more focused on a
statistical overview rather than a sequential trace of what&amp;#8217;s happened.
So, let&amp;#8217;s take a look at another instrumenting profiler, Perfetto.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Perfetto is in the domain of system level profilers, which I haven&amp;#8217;t had many
chances to work with.
In fact, I&amp;#8217;ve tended to avoid those options since they&amp;#8217;re quite frequently
built around server system profiling which can be both quite complex to setup
and focus around understanding even more complex systems that you might just
want to avoid.
Recently though I had to bite the bullet as the new complexity was justifiable.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Perfetto is an instrumenting profiler, but in this case the instrumentation
isn&amp;#8217;t inserted automatically.
Manual instrumentation isn&amp;#8217;t ideal, but it does mean that effort can be spent on
only recording relevant events in traces.
After instrumentation has been added to the source of an application,
the program can be run, and events can be used to create a trace via a logging
daemon.
With a daemon monitoring events, multiple applications can be logged
simultaneously, information about system state can be logged to the daemon,
and Perfetto showcases these features.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Being able to log out complex profiling traces is next to useless without good
data visualization, but Perfetto provides the needed tooling.
The logged data can be visualized in a
multi-threaded, multi-application, flame graph style view with additional
events flagged as needed, and metrics plotted over time.
If that doesn&amp;#8217;t sound like enough, the logged information can be queried via a
SQL style interface, which comes in handy for when you want to programmatically
aggregate results.
I do certainly miss the full trace summaries present in kcachegrind, so it isn&amp;#8217;t
perfect, but it does a solid job at answering: &quot;What happened at 50 seconds into
this program run?&quot;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;how-does-perfetto-help-you-visualize-program-traces&quot;&gt;How does Perfetto help you visualize program traces?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So, what does Perfetto look like in practice?
The main view is a collection of flamegraphs in separate tracks. Each track is
likely to be a different thread of execution or a separate process.
Each event in the flamegraph typically represents one function call, though
since they&amp;#8217;re user defined it&amp;#8217;s much more coarse than watching the true
callstack.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2023-03-08-perfetto.png&quot; alt=&quot;2023 03 08 perfetto&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The UI lets you see the total elapsed period of time recorded in a trace and
lets you smoothly zoom into smaller and smaller segments of time.
Vertically all of the tracks are stacked on each other highlighting the
individual applications recorded, individual threads within the applications,
and get detail information on any of the individual segments.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It&amp;#8217;s even possible to query the recorded events using SQL.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2023-03-08-perfetto3.png&quot; alt=&quot;2023 03 08 perfetto3&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Why would you want to query the profiling traces with SQL? Well, queries can be
used to aggregate performance with modest difficulty as opposed to the task
being a monumental exercise in reverse engineering of the formats used to store
the serialized traces.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;speed&quot;&gt;Speed&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You never want to encounter a Heisenbug, or in other words a bug which
disappears when it&amp;#8217;s observed.
We all have had them: the hardware glitch that can&amp;#8217;t replicate when you show it
to someone, a web browser that works only in developer mode&amp;#8230;&amp;#8203;
It&amp;#8217;s enough to build superstitions.
The same problem can and does arise in profiling because at the end of the day
by observing the program you&amp;#8217;re altering the speed it&amp;#8217;s being run at.
Even slight changes in the speed can make some bottlenecks disappear, new ones
appear, and when your tools are unreliable you can waste time fixing problems
that were never really there in the first place.
That&amp;#8217;s not even considering how changing the speed of a program can impact
various data races and other quirks of threading behavior.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So, ideally when profiling the speed of the underlying program should be as
close as is possible to normal operations.
Valgrind clearly violates that principle with 20x slowdowns, but that is why
those profiles tend to be useful primarily for compute bound profiling tasks.
Perfetto addresses this concern by making trace events lightweight and cheap to
record.
From &lt;a href=&quot;https://perfetto.dev/docs/instrumentation/track-events&quot;&gt;Perfetto
documentation&lt;/a&gt; we can see that every logged event is very cheap:&lt;/p&gt;
&lt;/div&gt;
&lt;table class=&quot;tableblock frame-all grid-all stretch&quot;&gt;
&lt;colgroup&gt;
&lt;col style=&quot;width: 42.8571%;&quot;&gt;
&lt;col style=&quot;width: 28.5714%;&quot;&gt;
&lt;col style=&quot;width: 28.5715%;&quot;&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Scenario&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Runtime on Pixel 3 XL&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Runtime on ThinkStation P920&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;TRACE_EVENT(&amp;#8230;&amp;#8203;)&lt;/code&gt; (disabled)&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;2 ns&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1 ns&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;TRACE_EVENT(&quot;cat&quot;, &quot;name&quot;)&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;285 ns&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;630 ns&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;TRACE_EVENT(&quot;cat&quot;, &quot;name&quot;, &amp;lt;lambda&amp;gt;)&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;304 ns&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;663 ns&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;TRACE_EVENT(&quot;cat&quot;, &quot;name&quot;, &quot;key&quot;, value)&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;354 ns&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;664 ns&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;DataSource::Trace(&amp;lt;lambda&amp;gt;)&lt;/code&gt; (disabled)&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;2 ns&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;1 ns&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;DataSource::Trace(&amp;lt;lambda&amp;gt;)&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;133 ns&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;58 ns&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;how-is-perfetto-integrated&quot;&gt;How is Perfetto integrated?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The biggest drawback of Perfetto is that events need to be manually added to the
application(s) being profiled.
Events are added through one of several macros or functions with a few of them
being documented in the table listing event tracing costs.
The primary macro is &lt;code&gt;TRACE_EVENT()&lt;/code&gt;, which creates a scope bound
event with a category, a name, and optionally a set of keys/values pairs.
Thanks to C++&apos;s RAII, trace event create a starting event along with an ending
event which is passed into the generated profiling trace.
Typically you&amp;#8217;ll see code along the lines of:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;/span&gt;void
func_name(int arg1) {
    TRACE_EVENT(&amp;quot;some_category&amp;quot;, &amp;quot;func_name&amp;quot;, &amp;quot;arg1&amp;quot;, arg1);
    //Do the normal work of the function
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;While the &lt;code&gt;TRACE_EVENT()&lt;/code&gt; macro is the most common method for sending events,
there&amp;#8217;s also more advanced methods which enable flags, counters, flows, and
as was shown in the previous table even faster data logging.
Counters for instance provide a way of storing a quantitative measure over time
such as worker&amp;#8217;s assigned to a task, the current framerate, system fan speed,
etc.
With a time series plot in the data visualization it&amp;#8217;s all the easier to hone
into the specific parts of the trace that you care to analyze.
Some of the functionality of Perfetto is still in flux, but as it stands it&amp;#8217;s
quite a powerful tool to add to a diagnostic toolbox.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;in-summary&quot;&gt;In Summary&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Overall Perfetto is a pretty neat profiling suite.
It&amp;#8217;s not the first hammer in my toolbox that I&amp;#8217;d bring out to optimize or
otherwise understand a codebase, but when you need a way of understanding a
multi-thread or multi-process system it&amp;#8217;s the sledge that will get the job done.
So, next time you have an eldritch horror of a computer system to tame, consider
checking Perfetto out.
Better yet, to explore the data visualization load up one of the pre-recorded
example traces available in the &lt;a href=&quot;https://ui.perfetto.dev/&quot;&gt;online user interface&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Sun, 12 Mar 2023 00:00:00 -0500</pubDate>
        <link>http://log.fundamental-code.com/2023/03/12/perfetto.html</link>
        <guid isPermaLink="true">http://log.fundamental-code.com/2023/03/12/perfetto.html</guid>
        
        
      </item>
    
      <item>
        <title>SVN-Externs Considered Harmful</title>
        <description>&lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;SVN externs are terrible and you shouldn&amp;#8217;t use them. Also don&amp;#8217;t use SVN if
you&amp;#8217;re able to avoid it, but that&amp;#8217;s likely already done in modern organizations.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;what-is-svn&quot;&gt;What is SVN?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Before digging into the meat of why svn externs are terrible, let&amp;#8217;s start off
with what SVN (Subversion) is; SVN is a system used to store source code and
assets for software projects. The main repository is stored on a remote server
and is represented as a collection of files and folders. You as a SVN user can
check out any subfolder or file within a repository. In the case of an
organization wanting multiple concurrent projects they&amp;#8217;re stored in separate
folders.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For one repository there is only a single history stored on the server that marches
forward linearly with the revision id tracker which consists of a number counting up
from the first commit.
So you will see r1 (revision 1) all the way up to whatever stage the current
history is in e.g. r14234.
What about tagging a copy of source code or branching it to do separate
development which later on gets merged? Well, SVN &apos;supports&apos; those features, but
at the same time it doesn&amp;#8217;t really&amp;#8230;&amp;#8203;
A tag or a branch is just copying the files in a project to another named
folder. There are conventions about the names and locations of those new
folders, but it&amp;#8217;s IMO a fairly weak feature.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;what-are-svn-externs&quot;&gt;What are SVN externs?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Let&amp;#8217;s say that you have in your SVN repository two projects:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;/span&gt;/ project1 / trunk
           / branches
/ project2 / trunk
           / branches&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Perhaps project 2 uses project 1, or in other words it depends on that project&amp;#8217;s
code and resources.
Dependency management is tricky and there&amp;#8217;s a number of approaches, one of which
is to copy code from project 1 into project 2, so when you build project 2, you
end up building both projects together.
However if you copy code from project 1, that means the copy can get out of
date.
So, instead you can reference the code from project 1 instead of copying it.
That&amp;#8217;s a good thing, right?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Well&amp;#8230;&amp;#8203;&amp;#8230;&amp;#8203; no, not from my point of view, at least without additional semantics.
Just inserting a reference isn&amp;#8217;t a great thing because when you&amp;#8217;re working on
project 2 you shouldn&amp;#8217;t be impacted negatively by changes in project 1 and thus
you don&amp;#8217;t want breaking changes to interrupt your development unless you&amp;#8217;re
agreeing to trying out those breaking changes.
SVN externs will take a copy of whatever you point them at, which &lt;em&gt;can&lt;/em&gt; be used
responsibly.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Consider the previous example again:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;/span&gt;/ project1 / trunk    /              src / library.h
           / branches / branch1    / src / library.h
           / tags     / release_v1 / src / library.h
                        release_v2 / src / library.h
/ project2 / trunk / dependencies / $external_resource
           / branches&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Here $external resource can point to a known working copy of project one which
isn&amp;#8217;t expected to change e.g. /project1/tags/release_v2 . If that&amp;#8217;s the target,
then when release_v3 is changed, then someone in project2 can update the library
they&amp;#8217;ve &lt;em&gt;chosen&lt;/em&gt; to use to /project1/tags/release_v3. But, here&amp;#8217;s where
svn-externs get to be evil: $external_resource can be /project1/trunk/,
/project1/branches/branch1, an individual file like
/project1/trunk/src/library.h, or even a reference to a different SVN repository
that you don&amp;#8217;t control at all e.g. https://example.com/totally/not/your/repository/library.h.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If it&amp;#8217;s any of those locations, the developers on project 1 can make changes
which without any release process are immediately reflected in project 2.
Why is that bad? Well, developers in project 1 aren&amp;#8217;t informed about who is
using their code as such by SVN. Who knows if a single file that you made is
essentially getting copied all over the place. Who knows if your self consistent
build process is going to be scrambled by being only partially copied elsewhere?
Since svn externs make it equally easy to grab parts of libraries and
live/tagged versions it encourages other projects to use internals (they don&amp;#8217;t
need the whole library) and use development copies (who wants to update versions
later on), which end poorly for people trying to work on the project getting
sliced up.
Those developers are left guessing who is using their code and how they&amp;#8217;re using
it since unless you write additional tooling it&amp;#8217;s near impossible to know how many
externs there are within a given repo.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you think that&amp;#8217;s bad, let me remark that recursive SVN externs are a thing
and I&amp;#8217;m thankful that it looks like they&amp;#8217;re rarely used. At least that&amp;#8217;s based
on both git-svn and git-svn-ext struggling with those cases.
Heck at least last time I tried to use it git-svn barely supported SVN externs.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Along the same lines of tooling breaking on externs, even good old commandline
svn starts to get ugly with externs.
SVN status, similar to other scm status tools, will output one line per file
that&amp;#8217;s modified.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So you might see:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;/span&gt;D  oldcode.rb
A  newcode.py
M  workingcode.sh&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;That status would indicate that you deleted a ruby file, added a python file,
and modified a shell script. The repository can contain many more files, but if
they&amp;#8217;re unmodified then you don&amp;#8217;t get any status information on them because
obviously you only care about what&amp;#8217;s changed.
Well, welcome to the world of SVN externs. &lt;strong&gt;Every&lt;/strong&gt; &lt;strong&gt;Single&lt;/strong&gt; &lt;strong&gt;Time&lt;/strong&gt; you run svn
status with a repository that has an extern it will end up having a X status on
the file/folder that&amp;#8217;s an extern reference. It doesn&amp;#8217;t matter if it&amp;#8217;s modified
or not.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So you might see for a repository that you haven&amp;#8217;t made any modifications:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;/span&gt;X internal/project1
X vendor/libA
X vendor/libB
X vendor/libC

Performing status on external item at &amp;#39;internal/project1&amp;#39;:
   X internal/project1/recursive-extern

Performing status on external item at &amp;#39;internal/project1/recursive-extern&amp;#39;:

Performing status on external item at &amp;#39;vendor/libA&amp;#39;:

Performing status on external item at &amp;#39;vendor/libB&amp;#39;:

Performing status on external item at &amp;#39;vendor/libC&amp;#39;:&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It&amp;#8217;s maddening&amp;#8230;&amp;#8203;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Not to mention that working with svn externs isn&amp;#8217;t via some &apos;svn extern&apos;
command, it&amp;#8217;s via &apos;svn propget&apos;, &apos;svn propset&apos;, etc. It&amp;#8217;s a thoroughly
unpleasant experience through and through.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In conclusion, next time you hear someone complain about git submodules, feel
free to say &quot;hey, at least it isn&amp;#8217;t svn externs&quot;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Tue, 20 Dec 2022 00:00:00 -0500</pubDate>
        <link>http://log.fundamental-code.com/2022/12/20/svn-externs-considered-harmful.html</link>
        <guid isPermaLink="true">http://log.fundamental-code.com/2022/12/20/svn-externs-considered-harmful.html</guid>
        
        
      </item>
    
      <item>
        <title>Building a plant table: (3/3) putting it together</title>
        <description>&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Well, this draft has been sitting unpublished for a while, but it&amp;#8217;s time for the
third part of my ad-hoc build series.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;With the two pre-requisite jigs out of the way
(&lt;a href=&quot;/2021/01/31/bandsaw-circle-jig.html&quot;&gt;1&lt;/a&gt;
&lt;a href=&quot;/2021/02/07/angled-bridle.html&quot;&gt;2&lt;/a&gt;) here&amp;#8217;s the main
project.
Essentially with winter arriving I had some typically outdoor plants which
needed to be moved back inside to avoid the frost.
My current home has reasonably high windows and narrow windowsills, so some
sort of table was needed for my plants to get a reasonable amount of sunlight.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I started out with a simple stool that I had built with pine reclaimed from an
old door. If you&amp;#8217;ve got a landlord who takes a door off the hinges and tells
you to get rid of it, what else are you going to do, eh?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So, while my stool does not look all that nice, it did give an initial sense of
scale and provided a baseline for what felt right.
Starting out, it was too short, stout, and generally too blocky.
So at a high level whatever I prototyped would end up being a slimmed down tall
stool.
To make the profile leaner, the top would end up being circular, the legs
thinner, and only three legs would get used.
Placing the legs at an angle would help with the outline of the design, though
it would complicate the joinery somewhat.
Having linkages from legs to all of their neighbors would be possible, but it
would be more complex to do as well as not being all that visually interesting.
So to stabilize the table all three would be joined to the top and joined
together at some point lower down in the frame&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2022-06-old-stool.jpg&quot; alt=&quot;2022 06 old stool&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 1. Old stool for comparison&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;With the general plan in mind it was a matter of estimating what sizes felt
right and rectifying that with what stock was available. While I had plants
which certainly could use a better perch, using up old material and `scrap&apos; was
a primary project goal. Starting out with the table top it was a matter of
placing a plant down on a sheet of cardboard, roughly tracing the desired
outline relative to one of the objects it was going to hold. From there without
any measurement a set of dividers could be used as a compass to get an accurate
circle which could be cut out.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2022-06-cardboard.jpg&quot; alt=&quot;2022 06 cardboard&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 2. Cardboard tracing&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The height of the table was initially measured by done by walking over to a
window, eyeballing where it feels like the plants should be and then just
placing a hand on my side at that height. While a smarter person would have
simply measured the distance directly the destination of the tables wasn&amp;#8217;t in
the same room as the tools themselves. So, some measurement error may have
accumulated, but that just adds to the character of the process.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As per the leg and top thickness, that was purely a constraint of what was
easily on hand without milling fresh boards, creating additional scrap.
Initially the plan was to make only one table, but hey who makes a project
without some scope creep.
The first part built out was the table tops. Each top is built out of a
collection of scrap pieces which admittedly didn&amp;#8217;t fit together all that well.
As such, it was a concern that some of the tops would well, come out horribly?
So far though, the low precision of a bandsaw &amp;amp; handtool combination has held
together well with standard wood glue.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I ended up making three tops with one on the thin side and two chunkier tops.
As they all turned out reasonably, so three tables it was.
When it came to the legs there was a similar split of enough stock for three
thin legs and six slightly thicker ones.
The thin stock was slightly shorter as well, so to have a set of unique tables
each one started out at a different height.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2022-06-template.jpg&quot; alt=&quot;2022 06 template&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 3. Mortise Template&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The build progressed fairly quickly from there.
The above template was used to locate the top mortises, then the lowers were
added about 2/3rds of the way down.
The linkages of the lowers were more cherry stock available at the same
rough dimensions as the legs themselves.
Once everything was together and with some light calculation the lowers were cut
to length and used to align a base joining plate.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The joining plate was a disk cut out on the circle jig (link), and the lowers
were manually marked on it for where they&amp;#8217;d fit into three recesses.
Not as accurate as layout out the locations ahead of time, but there was much
less math involved by seeing where parts naturally aligned.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The final results were pleasing in my opinion&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2022-06-final-results.jpg&quot; alt=&quot;2022 06 final results&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 4. Final tables&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2022-06-tops.jpg&quot; alt=&quot;2022 06 tops&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 5. Table tops&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2022-06-withplant.jpg&quot; alt=&quot;2022 06 withplant&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 6. With a houseplant&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Now it&amp;#8217;s not to say there weren&amp;#8217;t any flaws. A good set of photos could hide
them, but I&amp;#8217;ll mention them anyways. You can&amp;#8217;t advance your craft without
acknowledging where you can improve.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The bridle joints for the lower supports have some gaps due to the stock being
out of square. It&amp;#8217;s tricky for me to resolve this issue with my current tools,
but becoming more proficient at jointing stock with hand planes should reduce
this problem.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lower joints were connected asymmetrically. Doing all of the math for the
lower lengths, and how they were slotted into the joining plate would have
resolved this issue.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Gaps were present where the legs connected to the top. I&amp;#8217;m not sure of the
complete fix here, though I suspect that the angles were slightly off between
the upper tendon wall and the base of the tendon. Either that or the tendon
bases were just trimmed with my chisel too sloppily. Some better marking,
chiseling, and additional glue might resolve this particular issue.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Gaps within the table tops were initially visible. I&amp;#8217;m not sure how to fix
this one with my current set of tools, so perhaps additional tooling like a
sander with a right angle bed might help square up endgrain without creating
tear out you&amp;#8217;d expect from planes or routers.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I might eventually return to this project to make a set of plans, but for the
time being I&amp;#8217;ll leave a set of freecad sketches to anyone interested:
&lt;a href=&quot;/images/2022-06-plant-table.FCStd&quot;&gt;FreeCAD model&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;</description>
        <pubDate>Sun, 05 Jun 2022 00:00:00 -0400</pubDate>
        <link>http://log.fundamental-code.com/2022/06/05/plant-table.html</link>
        <guid isPermaLink="true">http://log.fundamental-code.com/2022/06/05/plant-table.html</guid>
        
        
      </item>
    
      <item>
        <title>Building a plant table: (2/3) quick angled bridle joints</title>
        <description>&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Like the previous post, we&amp;#8217;re working towards the construction of a plant table.
The design I was building attempted to look slim and modern.
One aspect of that was thin angled legs.
Thin legs aren&amp;#8217;t all that stable, on their own, so ideally there is a connection
to the table top and then a second connection lower down.
Attaching to the top and attaching further down the legs means angled jointery.
The intent was to have a linkage come off the legs about 2/3rds of the way down
and each linkage would connect to a base.
Initially I was planning on a simple angled mortise &amp;amp; tendon joint, however the
legs were thin enough that it seemed like a location which could easily crack
down the line.
Stylistically I could see either a proud tendon in the style of greene and
greene or a stopped tendon looking nice, but no need to overcomplicate things.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I ended up going with a T bridle joint. As for the angle of the legs, they were
all splayed out by an extra 10 degrees. With a 10 degree splay, it looks like:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2021-02-joint-diagram.png&quot; alt=&quot;2021 02 joint diagram&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 1. Angled T-bridle joint&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So, with that goal in mind, what&amp;#8217;s a good way to create the joint?
The leg has exposed jointery which is easy to mark so that piece is an everyday
normal bit of woodworking.
The angle within the horizontal linkages though is less trivial to do by hand.
In order to ensure the internal face of the linkage mated well with the leg
power tools.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Typically I end up using my mortise machine for cutting holes like that. In this
case it was just a matter of using the machine at an angle.
The built in fence and clamping wasn&amp;#8217;t designed for it, however with a
simple wedge and some support blocks we could get going.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2021-02-mortise-wide.jpg&quot; alt=&quot;2021 02 mortise wide&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 2. Mortise Wideshot&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Once we have a piece that we want to turn into a linkage, we can place it on the
wedge, use the support blocks to relieve pressure, and attach a single clamp to
hold it laterally.
By using the mortising machine like this the inside angled edge can be cut
cleanly.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;span class=&quot;image&quot;&gt;&lt;img src=&quot;/images/2021-02-mortise-close1.jpg&quot; alt=&quot;2021 02 mortise close1&quot; width=&quot;45%&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;image&quot;&gt;&lt;img src=&quot;/images/2021-02-mortise-close2.jpg&quot; alt=&quot;2021 02 mortise close2&quot; width=&quot;45%&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;After carving the initial hole it&amp;#8217;s possible to use the rest of the waste with a
bandsaw. As previously mentioned the jointery on the leg can be easily accessed,
but it is somewhat unwieldy for my power tools, though a table saw could make
quick work of the joint. In my case, some hand saws, a bit of chiseling, and a
router plane made fast work.
So, what does the result look like?
Something like:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;span class=&quot;image&quot;&gt;&lt;img src=&quot;/images/2021-02-result1.jpg&quot; alt=&quot;2021 02 result1&quot; width=&quot;45%&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;image&quot;&gt;&lt;img src=&quot;/images/2021-02-result2.jpg&quot; alt=&quot;2021 02 result2&quot; width=&quot;45%&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;image&quot;&gt;&lt;img src=&quot;/images/2021-02-result3.jpg&quot; alt=&quot;2021 02 result3&quot; width=&quot;45%&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;image&quot;&gt;&lt;img src=&quot;/images/2021-02-result4.jpg&quot; alt=&quot;2021 02 result4&quot; width=&quot;45%&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The last picture shows the three legs with the lowers linkages roughly lined up.
A cap will connect the lowers, but I&amp;#8217;ll leave that detail for the final post in
this series.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As per how well does it work, it does a decent job.
Since a through mortise is being created there is some occasional blowout.
The tearing could be minimized by using a wider sacrificial wedge, but I&amp;#8217;ll
leave that until next time.
While mortise machines aren&amp;#8217;t a common shop tool I figured I&amp;#8217;d throw this tool
tip out there for others or at worst, myself next time I approach a similar
task.&lt;/p&gt;
&lt;/div&gt;</description>
        <pubDate>Sun, 07 Feb 2021 00:00:00 -0500</pubDate>
        <link>http://log.fundamental-code.com/2021/02/07/angled-bridle.html</link>
        <guid isPermaLink="true">http://log.fundamental-code.com/2021/02/07/angled-bridle.html</guid>
        
        
      </item>
    
      <item>
        <title>Building a plant table: (1/3) starting with a circle jig</title>
        <description>&lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For a change of pace I&amp;#8217;m going to talk about a crafting project rather than
something related to music or programming.
To kick of hopefully some new retrospectives of projects, let&amp;#8217;s begin with a
three part journey into the construction of a simple custom `plant table&apos;.
This table was built a month or two back and it&amp;#8217;s the first nice furniture
project I&amp;#8217;ve completed without plans or other inspiration that I&amp;#8217;m satisfied with.
For an idea starting out as a way to use leftovers from a previous project
everything went fairly smoothly.
We&amp;#8217;ll get to the final project in the third part, but let&amp;#8217;s start off with some
jigs built along the way.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;My design called for a circular top, so being able to reliably cut circles of a
desired size was how I started off.
With a bit of searching I could have likely found something nearly identical
to the circle jig that I designed and built, but like other steps along the
way I wanted
to use what was on hand and what was easiest to setup giving the tooling of my own woodshop.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The basic principle behind any bandsaw circle jig is to allow for the workpiece
to be pivoted around a point and for that point to be positioned to be
perpendicular to the leading edge of the blade.
Different jigs accomplish this structure in their own ways, but the basic
principle holds true.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2021-01-jig-concept.png&quot; alt=&quot;2021 01 jig concept&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 1. Bandsaw Jig Concept, &lt;em&gt;only a few pieces are involved to use a bandsaw to consistently and quickly cut a circle&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The pivot could be constructed by gluing or clamping to a rotating base or
through other fixtures, but other plans I&amp;#8217;ve seen stick to the simpler option
of a partially exposed nail.
The nail sticks out just enough to dig into the bottom of the workpiece and let
it spin without falling off. It does leave a small mark on the base, but
house guests typically don&amp;#8217;t inspect the bottoms of tables.
Another design choice is how the woodworker can use the jib to start the cut.
As the miter slot is already there, I used that to both support the jig as well
as to guide the workpiece when getting started.
Lastly, since most of the full table project&amp;#8217;s design was done in an ad-hoc
fashion, the jig was also made to be adjustable (within reason).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Lastly, the jig was made to I used a simple mdf construction which tapered
into a point to allow for easy alignment of the jig along the miter slot.
Since most of the full table project&amp;#8217;s design was done in an ad-hoc fashion, the
jig was also made to be adjustable (within reason).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2021-01-bandsaw.jpg&quot; alt=&quot;2021 01 bandsaw&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 2. My frequently used bandsaw&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2021-01-jig-in-place.jpg&quot; alt=&quot;2021 01 jig in place&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 3. The jig installed ready to cut&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As can be seen in Fig. 3, the jig is mostly made out of some MDF.
The material was extra from I had from making a previous router template (
the same project which yielded some extra cherry which is used extensively in
this 3 part series).
The jig has a fixed base which can travel along the miter gauge, a slide which
has the nail pivot, and an optional clamp which can be used as both a handle and
as way to secure the slide in place.
The base of the jig has a pointed tip to help align the pivot point such that
the blade will be cutting along the circle&amp;#8217;s tangent.
The alignment can be seen below, and the tip is easy enough to see even when a
workpiece is being cut on top of the jig.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2021-01-jig-align.jpg&quot; alt=&quot;2021 01 jig align&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 4. Blade alignment&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;utility-so-does-it-work&quot;&gt;Utility: So, does it work?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The jig was not a perfect solution, but given the minimum radius of the blade
that I normally have on the bandsaw it works great.
I typically stick with a 1/2&quot; resawing blade as milling lumber to size
is one of the major jobs of my bandsaw.
The blade size limits me to 2 1/2&quot; radius circles, so the jig doesn&amp;#8217;t need to
work with much smaller ones for now.
Smaller crafts could be done with another blade, but well, I haven&amp;#8217;t even
gotten around to the classical bandsaw box projects nor the bandsaw animals
seen on some woodworking group pages.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2021-01-circle-output.jpg&quot; alt=&quot;2021 01 circle output&quot; width=&quot;50%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 5. Result of jig&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock warning&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-warning&quot; title=&quot;Warning&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;em&gt;When cutting I keep the blade guard much closer to the material. The guard is higher in pictures as to not obstruct the workpiece.&lt;/em&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As you can see, it certainly produces circles. The surface finish isn&amp;#8217;t perfect,
but that&amp;#8217;s more of a function of the blade that I&amp;#8217;ve chosen to use than the jig
itself. Either way the large circles are easy enough to sand.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;While I kept the initial table tops relatively simple the jig would also make it
possible to cut a bevel on the underside of the circular tops.
One pass would be needed to turn the rectangular stock into a cylinder.
A second pass could then be done after tilting the bandsaw table and then
repeating the process.
Of course one could argue that it would be simpler to use a router for such a
feature, but it depends on the amount of material getting removed.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;is-this-something-youd-want&quot;&gt;Is this something you&amp;#8217;d want?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Heh, my guess is likely not, but sometimes projects feel like a metaphorical
``If a tree falls in a forest and no one is around, does it make a sound?&apos;&apos;
situation.
Documenting what was done and why it was done is a key part of working on
projects even if no one goes to replicate it down the road. It adds perspective,
provides a chance to reflect on what was done, and helps to streamline the next
project along the way. So, the general design likely works and the measurements
should serve as a way of getting an idea of the scale of things.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For your own, make sure the material fits your miter slot in both the size of
the slot as well as the distance from the bandsaw blade.
The slot width/depth should be standardized, but that sort of assumption has
bitten me before.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2021-01-circle-jig-view.png&quot; alt=&quot;2021 01 circle jig view&quot; width=&quot;60%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 6. Rough plans&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Full FreeCAD files are &lt;a href=&quot;/images/2021-01-circle-jig.FCStd&quot;&gt;available&lt;/a&gt;, though
keep in mind this project has acted as my first hands on less in FreeCAD and
more generally CAD in general. I mostly stick to non-computerized methods, but
those methods are not great for building long term documentation.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Sun, 31 Jan 2021 00:00:00 -0500</pubDate>
        <link>http://log.fundamental-code.com/2021/01/31/bandsaw-circle-jig.html</link>
        <guid isPermaLink="true">http://log.fundamental-code.com/2021/01/31/bandsaw-circle-jig.html</guid>
        
        
      </item>
    
      <item>
        <title>MRuby-Zest: a Scriptable Audio GUI Framework</title>
        <description>&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;screenshot-of-framework-in-action&quot;&gt;Screenshot of framework in action&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;http://zynaddsubfx.sourceforge.net/images/zyn-fusion-osc.png&quot; alt=&quot;zyn fusion osc&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;abstractintro-from-paper&quot;&gt;Abstract/Intro from paper&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Audio tools face a set of uncommon user interface
design and implementation challenges. These constraints make
high quality interfaces within the open
source realm particular difficult to execute on volunteer time.
The challenges include producing a
unique identity for the application, providing easy
to use controls for the parameters of the application,
and providing interesting ways to visualize the data
within the application. Additionally, existing toolkits
produce technical issues when embedding within
plugin hosts. MRuby-Zest is a new toolkit that was
build while the ZynAddSubFX user interface was
rewritten. This toolkit possesses unique characteristics
within open source toolkits which target the
problems specific to audio applications.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;MRuby-Zest was created to address long standing issues in the &lt;a href=&quot;http://zynaddsubfx.sf.net&quot;&gt;ZynAddSubFX&lt;/a&gt; user interface. The MRuby-Zest framework was built
with 5 characteristics in mind.
MRuby-Zest should be:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Scriptable:
Implementation uses a first class higher level language&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dynamically Resizable: Fluid layouts which
do not have any fixed sizes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hot Reloadable: Reloads a modified implementation without restarting&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Embeddable: Can be placed within another UI without conflicts&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Maintainable: Relatively simple to read and write GUI code&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To do this MRuby-Zest takes Qt&amp;#8217;s &lt;a href=&quot;https://doc.qt.io/qt-5/qmlfirststeps.html&quot;&gt;QML language&lt;/a&gt;,
replaced the scripting language with &lt;a href=&quot;https://github.com/mruby/mruby&quot;&gt;Ruby&lt;/a&gt;,
integrated it with the &lt;a href=&quot;https://github.com/memononen/nanovg&quot;&gt;nanovg&lt;/a&gt; OpenGL
rendering library, and began to leverage parameter metadata that ZynAddSubFX
produces via the &lt;a href=&quot;https://github.com/fundamental/rtosc&quot;&gt;rtosc&lt;/a&gt; library. Building
the toolkit within Ruby instead of on-top of a pre-existing C/C++ toolkit has
made MRuby-Zest particularly flexible when it comes to expanding it&amp;#8217;s
feature-set.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;more-information&quot;&gt;More information&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://media.ccc.de/v/lac2018-38-mruby_zest_a_scriptable_audio_gui_framework&quot;&gt;video
of LAC-2018 presentation&lt;/a&gt;, &lt;a href=&quot;http://lac.linuxaudio.org/2018/pdf/38-paper.pdf&quot;&gt;LAC
2018 paper&lt;/a&gt;, &lt;a href=&quot;https://github.com/mruby-zest&quot;&gt;source code&lt;/a&gt;,
&lt;a href=&quot;../../../images/2018-zest-slides.pdf&quot;&gt;slides&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Sat, 16 Jun 2018 00:00:00 -0400</pubDate>
        <link>http://log.fundamental-code.com/2018/06/16/mruby-zest.html</link>
        <guid isPermaLink="true">http://log.fundamental-code.com/2018/06/16/mruby-zest.html</guid>
        
        
      </item>
    
      <item>
        <title>Total Variation Denoising</title>
        <description>&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Working with data is an important part of my day-to-day work.
No matter if it&amp;#8217;s speech, music, images, brain waves, or some other stream of
data there&amp;#8217;s plenty of it and there&amp;#8217;s always some quality issue associated with
working with the data.
In this post I&amp;#8217;m interested in providing an introduction to one technique which
can be utilized to reduce the amount of noise present in some of these classes
of signals.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Noise might seem abstract at first, but it&amp;#8217;s relatively simple to quantify it.
If the original signal, $x$, is known, then the noise, $n$, is any
deviation in the observation, $y$, from the original signal.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;$$y = x + n$$&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Typically the deviation is measured via the squared error across all elements
in a given signal:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;$$\text{error} = ||x-y||^2_2 = \sum_i (x_i-y_i)^2$$&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;When only the noisy signal, $y$, is observed it is difficult to separate the
noise from the signal.
There is a wealth of literature on separating noise and many algorithms focus
on identifying underlying repeating structures.
The algorithm that this post focuses on is one which reduces the total
variation over a given signal.
One example of a signal with little variation is a step function:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/code/2017-tv-clean.png&quot; alt=&quot;2017 tv clean&quot; width=&quot;70%&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A step function only has one point where a sample of the signal varies from the
previous sample.
The Total Variation denoising technique focuses on minimizing the number of
points where the signal varies and the amount the signal varies at each point.
Restricting signal variation works as an effective denoiser as many types of
noise (e.g. white noise) contain much more variation than the underlying signal.
At a high level Total Variation (TV) denoising works by minimizing the cost of
the output $y$ given input signal $x$ as described below:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;$$\text{cost} = \text{error}(x, y) + \text{weight}*\text{sparseness}(\text{transform}(y))$$&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Mathematically the full cost of TV denoising is:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;$$
\begin{aligned}
\text{cost} &amp;amp;= \text{error} + \text{TV-cost} \\
\text{cost} &amp;amp;= ||x-y||_2^2 + \lambda ||y||_{TV} \\
||y||_{TV}  &amp;amp;= \sum |y_i-y_{i-1}|
\end{aligned}$$&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To see how the above optimization can recover a noisy signal, lets look at a
noisy version of the step function:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/code/2017-tv-noised.png&quot; alt=&quot;2017 tv noised&quot; width=&quot;70%&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;After using the TV norm to denoise only a few points of variation are left:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/code/2017-tv-denoised.png&quot; alt=&quot;2017 tv denoised&quot; width=&quot;70%&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The process of getting the final TV denoised output involves many iterations of
updating where variations occur.
Over the course of iterations opposing variations cancel out and smaller
variations are driven to $\Delta y = 0$.
As the number of non-zero points increase a sparse solution is produced and
noise is eliminated.
For higher values of the TV weight, $\lambda$, the solution will be more sparse.
For the noisy step function, $y$ and $\Delta y$ over several iterations look
like:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/code/2017-tv-tv-example.png&quot; alt=&quot;2017 tv tv example&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For piecewise constant signals, the TV norm alone works quite well, however
there are problems which arise with the output when the original signal is not
a series of flat steps.
To illustrate this consider a piecewise linear signal.
When TV denoising is applied a stair stepping effect is created as shown below:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/code/2017-tv-gstv-example.png&quot; alt=&quot;2017 tv gstv example&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;One of the extensions to TV based denoising is to add &apos;group sparsity&apos; to the
cost of variation.
Standard TV denoising results in a sparse set of points where there is non-zero
variation, resulting in a few piecewise constant regions.
With the TV norm, the cost of varying at point $\Delta y_i$ within the signal does not
depend upon which other, $\Delta y_j,\Delta y_k,\text{etc}$, points vary.
Group Sparse Total Variation, GSTV, on the other hand reduces the cost for
smaller variation in nearby points.
GSTV therefore generally produces smoother results with more gentle curves for
higher order group sparsity values as variation occurs over several nearby
points rather than a singular one.
Applying GSTV to the previous example results in a much smoother representation
which more accurately models the underlying data.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/code/2017-tv-corn-tv.png&quot; alt=&quot;2017 tv corn tv&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Now that some artificial examples have been investigated, lets take a brief
look at some real world data.
One example of data which is expected to have relatively few points of abrupt
change is the price of goods.
In this case we&amp;#8217;re looking at the price of corn in the United States 2000 to
2017 in USD per bushel as retrieved from
&lt;a href=&quot;http://www.farmdoc.illinois.edu/manage/uspricehistory/USPrice.asp&quot; class=&quot;bare&quot;&gt;http://www.farmdoc.illinois.edu/manage/uspricehistory/USPrice.asp&lt;/a&gt; .
With real data it&amp;#8217;s harder to define noise (or what part of the signal is
unwanted);
However, by using higher levels of denoising the overall trends can be
observed within the time-series data:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/code/2017-tv-corn-gstv.png&quot; alt=&quot;2017 tv corn gstv&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If this short into was interesting I&amp;#8217;d recommend trying out TV/GSTV techniques
on your own problems.
For more in depth information there&amp;#8217;s a good few papers out there on the topic
with the original GSTV work being:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I. W. Selesnick and P.-Y. Chen, &apos;Total Variation Denoising with Overlapping
Group Sparsity&apos;, IEEE Int. Conf. Acoust., Speech, Signal Processing (ICASSP).
May, 2013.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://eeweb.poly.edu/iselesni/gstv/&quot; class=&quot;bare&quot;&gt;http://eeweb.poly.edu/iselesni/gstv/&lt;/a&gt; - contains above paper as well as a
MATLAB implementation&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And if you&amp;#8217;re using Julia, feel free to grab my re-implementation of Total
Variation and Group Sparse Total Variation at
&lt;a href=&quot;https://github.com/fundamental/TotalVariation.jl&quot; class=&quot;bare&quot;&gt;https://github.com/fundamental/TotalVariation.jl&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</description>
        <pubDate>Sat, 02 Sep 2017 00:00:00 -0400</pubDate>
        <link>http://log.fundamental-code.com/2017/09/02/total-variation-denoising.html</link>
        <guid isPermaLink="true">http://log.fundamental-code.com/2017/09/02/total-variation-denoising.html</guid>
        
        
      </item>
    
      <item>
        <title>Linux &amp;amp; Multi-Screen Touch Screen Setups</title>
        <description>&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;While working on the Zyn-Fusion UI I ended up getting a touch screen to help
with the testing process.
After getting the screen, buying several incorrect HDMI cables, and setting up
the screen I found out that the touch events weren&amp;#8217;t working as expected.
In fact they were often showing up on the wrong screen.
If I disabled my primary monitor and only used the touch screen, then events
were spot on, so this was only a multi-monitor setup issue.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So, what caused the problem and how can it be fixed?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Well, by default the mouse/touch events which were emitted by the new screen
were scaled to the total available area treating multiple screens as a single
larger screen.
Fortunately X11 provides one solution through xinput.
Just running the xinput tool lists out a collection of devices which provide
mouse and keyboard events to X11.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre&gt;mark@cvar:~$ xinput
| Virtual core pointer                          id=2    [master pointer  (3)]
|   &amp;gt; Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
|   &amp;gt; PixArt USB Optical Mouse                  id=8    [slave  pointer  (2)]
|   &amp;gt; ILITEK Multi-Touch-V3004                  id=11   [slave  pointer  (2)]
| Virtual core keyboard                         id=3    [master keyboard (2)]
    &amp;gt; Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    &amp;gt; Power Button                              id=6    [slave  keyboard (3)]
    &amp;gt; Power Button                              id=7    [slave  keyboard (3)]
    &amp;gt; AT Translated Set 2 keyboard              id=9    [slave  keyboard (3)]
    &amp;gt; Speakup                                   id=10   [slave  keyboard (3)]&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In this case the monitor is device 11 which has it&amp;#8217;s own set of properties.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre&gt;mark@cvar:~$ xinput list-props 11
Device &apos;ILITEK Multi-Touch-V3004&apos;:
        Device Enabled (152):   1
        Coordinate Transformation Matrix (154): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
        Device Accel Profile (282):     0
        Device Accel Constant Deceleration (283):       1.000000
        Device Accel Adaptive Deceleration (284):       1.000000
        Device Accel Velocity Scaling (285):    10.000000
        Device Product ID (272):        8746, 136
        Device Node (273):      &quot;/dev/input/event13&quot;
        Evdev Axis Inversion (286):     0, 0
        Evdev Axis Calibration (287):   &amp;lt;no items&amp;gt;
        Evdev Axes Swap (288):  0
        Axis Labels (289):      &quot;Abs MT Position X&quot; (689), &quot;Abs MT Position Y&quot; (690), &quot;None&quot; (0), &quot;None&quot; (0)
        Button Labels (290):    &quot;Button Unknown&quot; (275), &quot;Button Unknown&quot; (275), &quot;Button Unknown&quot; (275), &quot;Button Wheel Up&quot; (158), &quot;Button Wheel Down&quot; (159)
        Evdev Scrolling Distance (291): 0, 0, 0
        Evdev Middle Button Emulation (292):    0
        Evdev Middle Button Timeout (293):      50
        Evdev Third Button Emulation (294):     0
        Evdev Third Button Emulation Timeout (295):     1000
        Evdev Third Button Emulation Button (296):      3
        Evdev Third Button Emulation Threshold (297):   20
        Evdev Wheel Emulation (298):    0
        Evdev Wheel Emulation Axes (299):       0, 0, 4, 5
        Evdev Wheel Emulation Inertia (300):    10
        Evdev Wheel Emulation Timeout (301):    200
        Evdev Wheel Emulation Button (302):     4
        Evdev Drag Lock Buttons (303):  0&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Notably xinput provides a property to describe a coordinate transformation which
can be used to remap the x and y values of the cursor events.
The transformation matrix here is a 3x3 matrix used to transform 2D coordinates
and is a fairly common sight in computer graphics.
It translates from \((x,y)\) to \((x&apos;,y&apos;)\) as defined by:&lt;/p&gt;
&lt;/div&gt;
$$
\begin{bmatrix}
x&apos; \\
y&apos; \\
1
\end{bmatrix}

=

\begin{bmatrix}
a &amp; b &amp; c\\
d &amp; e &amp; f\\
h &amp; i &amp; j
\end{bmatrix}
\times
\begin{bmatrix}
x \\
y \\
1
\end{bmatrix}
$$
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The transformation matrix allows for stretching, shearing, translation,
flipping, scaling, etc.
For the sorts of problems you may see introduced by a multi-monitor setup I
would only expect people to care about translating (\(t\)) the events
and then re-scaling (\(s\)) them to the offset area.
Using these two parameters, the transformation matrix equation is simplified to:&lt;/p&gt;
&lt;/div&gt;
$$
\begin{bmatrix}
x&apos; \\
y&apos; \\
1
\end{bmatrix}

=

\begin{bmatrix}
s_x &amp; 0 &amp; t_x\\
0 &amp; s_y &amp; s_y\\
0 &amp; 0 &amp; 1
\end{bmatrix}
\times
\begin{bmatrix}
x \\
y \\
1
\end{bmatrix}
$$
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Or without the matrix representation:&lt;/p&gt;
&lt;/div&gt;
$$
\begin{aligned}
x&apos; &amp;= s_x  x + t_x\\
y&apos; &amp;= s_y  y + t_y
\end{aligned}
$$
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;With that background out of the way, let&amp;#8217;s see how this applied to my specific
monitor setup:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/images/2017-monitors.png&quot; alt=&quot;2017 monitors&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As I mentioned earlier the touch events were scaled to the dimensions of the
larger virtual screen.
Since the touch screen is larger this means the y axis is mapped correctly and
the x axis is mapped for pixels 0..3200 (both screens) instead of pixels
1281..3200 (left screen only).
Since the xinput scales theses parameters based upon the total screen size, we
can divide by the total x size (3200) to learn that the x axis maps to 0..1
rather than 0.4..1.0.
Solving the above equations we can remap the touch events using \(s_x=0.6\) and
\(t_x=0.4\).
This results in the transformation matrix:&lt;/p&gt;
&lt;/div&gt;
$$
\begin{bmatrix}
0.6 &amp; 0 &amp; 0.4\\
0 &amp; 1 &amp; 0\\
0 &amp; 0 &amp; 1
\end{bmatrix}
$$
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The last step is to provide the new transformation matrix to xinput:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre&gt;xinput set-prop 11 &apos;Coordinate Transformation Matrix&apos; 0.6 0 0.4 0 1 0 0 0 1&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Now cursor events map onto the correct screen accurately and the code to change
the xinput properties can be easily put into a shell script.&lt;/p&gt;
&lt;/div&gt;</description>
        <pubDate>Tue, 04 Jul 2017 00:00:00 -0400</pubDate>
        <link>http://log.fundamental-code.com/2017/07/04/linux-multi-touch.html</link>
        <guid isPermaLink="true">http://log.fundamental-code.com/2017/07/04/linux-multi-touch.html</guid>
        
        
      </item>
    
      <item>
        <title>Profiling MRuby Code</title>
        <description>&lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I loathe inefficient, slow, or bloated software.
Unfortunately, I&amp;#8217;ve written plenty of code that&amp;#8217;s terrible in this sense and if
you program frequently, then I&amp;#8217;d wager you have written quite a few inefficient
lines of code as well.
Fortunately code isn&amp;#8217;t written in stone after the first pass and we as
programmers can optimize it.
Most of the time the speed of a single line of code doesn&amp;#8217;t matter or contribute
to the overall inefficiency in an application.
Sometimes, though, a change to a few lines can make all the difference.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;profilers&quot;&gt;Profilers&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Finding those lines of code however is a challenging task unless you have access
to some means of profiling the program and finding out which sections of code
are run the most frequently and the lines which use up the most time.
Each programming language tends to have it&amp;#8217;s own tools, though if you&amp;#8217;re
tackling a mixed ruby/C codebase then you might be familiar with:
&lt;a href=&quot;https://github.com/ruby-prof/ruby-prof&quot;&gt;RubyProf&lt;/a&gt;,
&lt;a href=&quot;http://valgrind.org/docs/manual/cl-manual.html&quot;&gt;callgrind&lt;/a&gt;,
&lt;a href=&quot;https://sourceware.org/binutils/docs/gprof/&quot;&gt;gprof&lt;/a&gt;,
or the &lt;a href=&quot;http://poormansprofiler.org/&quot;&gt;poor man&amp;#8217;s profiler&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Based upon the title of this article I&amp;#8217;m guessing that you may be interested in
profiling the embeddable ruby implementation &apos;mruby&apos;.
While I was developing my own application using mruby, I tended to profile ruby
code with timers:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre&gt;before = Time.new()
run_routine()
after  = Time.new()
puts(&quot;run_routine took #{1000*(after-before)} ms&quot;)&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This provided limited information, but it helped direct the development to a
few hotspots and then additional profiling of the C portion of the codebase was
done with callgrind.
Callgrind for me is a holy grail of profiling CPU bound programs.
Through &lt;a href=&quot;https://kcachegrind.github.io/html/Home.html&quot;&gt;kcachegrind&lt;/a&gt; it provides
an easy to explore callgraph, relative and absolute timing information, source
level information, and information at the assembly level.
Callgrind combined with kcachgrind make it easy to understand where the hotspots
for a program are, what is the callgraph that generates these issues, and what
compiled assembly creates the issues.
If you&amp;#8217;re trying to optimize a C/C++ codebase just use callgrind.
It slows down the overall execution by at least an order of magnitude, but the
information provided is superb.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;mruby-profiler&quot;&gt;MRuby-Profiler&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Back to mruby, the initial timer based profiling doesn&amp;#8217;t have many of the
advantages of callgrind, or other profiler tools.
Adding timers was a manual process, it provided very coarse information,
and it provided only a limited slice of the whole program.
As such, a full mruby VM profiler should be preferred.
The &lt;a href=&quot;https://github.com/miura1729/mruby-profiler&quot;&gt;mruby-profiler&lt;/a&gt; gem is one such tool.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;MRuby-profiler works by observing the progression of the mruby virtual machine
via a callback which is invoked every time the VM executes a new ruby instruction.
This allows for the profiler to have an &lt;strong&gt;exact&lt;/strong&gt; count for how many times an
instruction is invoked, a reasonably accurate time for the execution of each
instruction, information about the call graph, and often detailed line-by-line
source level times.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Now that the mruby-profiler gem is introduced, let&amp;#8217;s take a look at a simple
example run.
In the top-left you&amp;#8217;ll see a simple ruby program, on the right mruby-profiler&amp;#8217;s source
annotated output, and in the bottom-left mruby-profiler&amp;#8217;s no-source VM instruction only
output.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-left&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;test_code&lt;/span&gt;
    var1 &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;[]&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;100.&lt;/span&gt;times &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;do&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;x&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;
        var1 &lt;span style=&quot;color: #666666&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; x
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;

    var1&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;each_with_index &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;do&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;x, ind&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;
        var1&lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;ind&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;2.0*&lt;/span&gt;x &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;4.3*&lt;/span&gt;x&lt;span style=&quot;color: #666666&quot;&gt;**2.0&lt;/span&gt;
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;

    var1
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;

test_code&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-right&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;0000&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00011&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;test_code&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00002&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_TCLASS&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00003&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LAMBDA&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;      I(&lt;span style=&quot;color: #666666&quot;&gt;+1&lt;/span&gt;)   &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00003&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_METHOD&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:test_code&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00003&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0001&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00004&lt;/span&gt;     var1 &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;[]&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00004&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_ARRAY&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0002&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00186&lt;/span&gt;     &lt;span style=&quot;color: #666666&quot;&gt;100.&lt;/span&gt;times &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;do&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;x&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00002&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADI&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00005&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LAMBDA&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      I(&lt;span style=&quot;color: #666666&quot;&gt;+1&lt;/span&gt;)   &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00007&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_SENDB&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:times&lt;/span&gt;  &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00172&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0003&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00957&lt;/span&gt;         var1 &lt;span style=&quot;color: #666666&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; x
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00142&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_GETUPVAR&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;       &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00128&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00479&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:&amp;lt;&amp;lt;&lt;/span&gt;     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00208&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0004&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00000&lt;/span&gt;     &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0005&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00000&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0006&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00186&lt;/span&gt;     var1&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;each_with_index &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;do&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;x, ind&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00002&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00004&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LAMBDA&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      I(&lt;span style=&quot;color: #666666&quot;&gt;+2&lt;/span&gt;)   &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00006&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_SENDB&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:each_with_index&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00175&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0007&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.03609&lt;/span&gt;         var1&lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;ind&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;2.0*&lt;/span&gt;x &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;4.3*&lt;/span&gt;x&lt;span style=&quot;color: #666666&quot;&gt;**2.0&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00142&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADL&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      L(&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;)    ; &lt;span style=&quot;color: #666666&quot;&gt;0.1&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00139&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADL&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      L(&lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;)    ; &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00142&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R6&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00167&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MUL&lt;/span&gt;        &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:*&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00145&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_ADD&lt;/span&gt;        &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:+&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00148&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADL&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      L(&lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;)    ; &lt;span style=&quot;color: #666666&quot;&gt;4.3&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00141&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R6&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00143&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADL&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R7&lt;/span&gt;      L(&lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;)    ; &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00850&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R6&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:**&lt;/span&gt;     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00157&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MUL&lt;/span&gt;        &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:*&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00152&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_ADD&lt;/span&gt;        &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:+&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00158&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_GETUPVAR&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;       &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00128&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R6&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00141&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R7&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00647&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:[]=&lt;/span&gt;    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;
      &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00209&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0008&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00000&lt;/span&gt;     &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0009&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00000&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0010&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00004&lt;/span&gt;     var1
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00004&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0011&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00000&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0012&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00000&lt;/span&gt;
&lt;span style=&quot;color: #666666&quot;&gt;0013&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00225&lt;/span&gt; test_code
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00001&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADSELF&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00005&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:test_code&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00218&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_STOP&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-left&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #880000&quot;&gt;Fixnum&lt;/span&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;#times 0.01822&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00002&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00001&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADSELF&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00011&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:block_given?&lt;/span&gt;   &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00001&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_JMPNOT&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00001&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_JMP&lt;/span&gt;                &lt;span style=&quot;color: #666666&quot;&gt;005&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00000&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADSELF&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00000&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADSYM&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:times&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00000&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:to_enum&lt;/span&gt;        &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00000&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00001&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADI&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00001&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_JMP&lt;/span&gt;                &lt;span style=&quot;color: #666666&quot;&gt;007&lt;/span&gt;
   &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00128&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;
   &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00142&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;
   &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00546&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:call&lt;/span&gt;   &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
   &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00128&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;
   &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00164&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_ADDI&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:+&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
   &lt;span style=&quot;color: #666666&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00128&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;
   &lt;span style=&quot;color: #666666&quot;&gt;101&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00144&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;
   &lt;span style=&quot;color: #666666&quot;&gt;101&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00138&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADSELF&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;
   &lt;span style=&quot;color: #666666&quot;&gt;101&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00143&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LT&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:&amp;lt;&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
   &lt;span style=&quot;color: #666666&quot;&gt;101&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00138&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_JMPIF&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;-09&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00001&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADSELF&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;
     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0.00002&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;From these outputs, we can see that the most expensive line in the program is
line 7 which takes roughly 36 ms to execute over the course of this entire
program.
The &apos;**&apos; operator takes a large portion of that time (8.5 ms) and is executed
100 times as expected.
The first &apos;100.times&apos; loop takes 1.8 ms + 9.5 ms + 18.2 ms (from the overhead of
Fixnum#times itself).
Within the output, line numbers, source code, VM instruction call counts, and VM
instruction self times can be seen fairly clearly.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;complications-in-profiling&quot;&gt;Complications In Profiling&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The mruby-profiler gem makes profiling much easier, however there are a few
limits with it&amp;#8217;s current implementation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;entering-and-exiting-the-mruby-vm&quot;&gt;Entering and Exiting The MRuby VM&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The timers within mruby-profiler are relatively simple and in most code they
tend to work very well.
They do fail when interacting with any program which ends up doing a fair amount
of work within C which ends up calling ruby methods from C.
To elaborate on that, let&amp;#8217;s first look at how mruby-profiler calculates how much
time is spent at a given mruby opcode.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The mruby-profiler gem uses the code fetch hook within the mruby VM.
Every time an opcode is executed by the mruby VM the code fetch hook is called.
MRuby-profiler records the time when an instruction is fetched.
When the next fetch occurs the difference in time is assumed to be the amount of
time spent in the previous instruction.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Generally this model works well.
For normal ruby code it&amp;#8217;s completely accurate, for ruby calling simple C
routines the appropriate amount of time is given to the OP_SEND instruction
which lead to the C call, but it fails with a mixture of C/ruby calls.
Consider the below sequence of events:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;C code calls one ruby method&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;C code works on a long running task&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;C code calls another ruby method&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;During step 2 no ruby opcodes will be observed by mruby-profiler.
Thus, when step 3 occurs and a new VM opcode is fetched, then all the time that
was spent in step 2 is attributed to the last instruction in step 1.
Typically the last instruction of a mruby method would be OP_RETURN.
So, if you spot an OP_RETURN which is taking much more time than it should, be
aware that it may be counting time spent in a calling C function.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;a-lack-of-cumulative-child-function-time&quot;&gt;A lack of cumulative child function time&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In general I&amp;#8217;d say having method/instruction time presented as &apos;self-time&apos; is
preferable in a reasonably well architected system.
Self-time presents how much time could effectively be saved by optimizing the
method by itself without considering the rest of the code it ends up calling.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Self-time, however, can create a few problems with interpreting the results of
mruby-profiler.
If a hotspot function is called a large number of times, it can be tricky to
backtrack which functions called it a significant number of times or with a
particular type of data which took the hotspot function longer to evaluate.
The lack of cumulative times also make it hard to evaluate if a particular
function is &apos;expensive to call&apos;.
It is possible to have an &apos;expensive to call&apos; function which does not use a
significant amount of time with called functions which also do not use much time.
If, however, there is a sufficiently deep call stack, then an innocuous function can
still become very expensive in the cumulative sense (i.e. &quot;death by a million cuts&quot;)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The last issue is one that&amp;#8217;s more ruby specific.
I&amp;#8217;d say it&amp;#8217;s fair to say that if you enjoy ruby you use blocks&amp;#8230;&amp;#8203; You use them a
&lt;em&gt;lot&lt;/em&gt;.
For those of you unfamiliar with what a block is here&amp;#8217;s a simple example:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-left&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;object&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;method &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;do&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;optional_args&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;
    work_on_block
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-right&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;irep &lt;span style=&quot;color: #666666&quot;&gt;0x9b433e0&lt;/span&gt; nregs&lt;span style=&quot;color: #666666&quot;&gt;=3&lt;/span&gt; nlocals&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt; pools&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt; syms&lt;span style=&quot;color: #666666&quot;&gt;=2&lt;/span&gt; reps&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;file&lt;/span&gt;: tmp&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;rb
    &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;000&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADSELF&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;001&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:object&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LAMBDA&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;      I(&lt;span style=&quot;color: #666666&quot;&gt;+1&lt;/span&gt;)   &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;003&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SENDB&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:method&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;004&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_STOP&lt;/span&gt;

irep &lt;span style=&quot;color: #666666&quot;&gt;0x9b494a8&lt;/span&gt; nregs&lt;span style=&quot;color: #666666&quot;&gt;=5&lt;/span&gt; nlocals&lt;span style=&quot;color: #666666&quot;&gt;=3&lt;/span&gt; pools&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt; syms&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt; reps&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;file&lt;/span&gt;: tmp&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;rb
    &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;000&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;001&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADSELF&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:work_on_block&lt;/span&gt;  &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;003&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In the ruby code :method is called with the block (do..end).
The block is encoded as a lambda function (the second irep) and method ends up calling
the lambda.
Just like in the very first example, with Fixnum#times, the cost involved with :method
is associated with :method&amp;#8217;s implementation and not the object.method call.
When the block accepting method adds a significant amount of overhead it&amp;#8217;s very
easy to overlook using self-time and you should be aware of it when profiling.
In the case of iteration, we&amp;#8217;ll revisit block-method overhead later in this article.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;While at the moment mruby-profiler doesn&amp;#8217;t present cumulative time information
it does capture it from the MRuby VM (or at least it appeared to when I looked
at the source).
It&amp;#8217;s not in the most convenient format, but at least the data is there, it&amp;#8217;s just
the analysis which needs to be updated (and that&amp;#8217;s all ruby).
The mruby-profiler gem  is still missing the functionality, but I imagine it could
be added reasonably easily in the future.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;bugs&quot;&gt;Bugs&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Of course another limitation of using both mruby and mruby-profiler is that both
of them are going to have more bugs than other tools with more widespread
use.
When I initially found mruby-profiler it tended to crash in a variety of ways
for the codebase I was profiling (I&amp;#8217;d recommend using the fixes I&amp;#8217;ve proposed to
mruby-profiler via a pull request if it hasn&amp;#8217;t yet been merged).
When I initially began using MRuby I encountered a few bugs, though MRuby has
become a fair bit more stable over the past year.
Lastly, while mruby-profiler does provide an output for kcachgrind, be aware
that it is incomplete and there are some bugs in the output (though it is
entirely unclear if they are from mruby&amp;#8217;s debug info or a bug within
mruby-profiler).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;deciding-when-to-move-from-ruby-to-c&quot;&gt;Deciding when to move from ruby to C&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;One of the great things about MRuby (and one of the major reasons why I&amp;#8217;ve used
it for a sizable user interface project) is that it&amp;#8217;s extremely easy to move a
routine from ruby to C.
Of course it&amp;#8217;s still easier to leave code as ruby (otherwise I would have just
written everything in C), so what tasks does ruby struggle with?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;heavy-numerical-tasks&quot;&gt;Heavy numerical tasks&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Like most interpreted languages, heavy mathematical operations aren&amp;#8217;t &apos;fast&apos;.
Of course, they may be fast enough, but major gains can be made by using a
compiled and heavily optimized language like C.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Consider the below ruby code:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-left&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;func&lt;/span&gt;(array)
  array&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;map &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;do&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;x&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;
    &lt;span style=&quot;color: #880000&quot;&gt;Math&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;abs(&lt;span style=&quot;color: #880000&quot;&gt;Math&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;sin(x &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;*&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;8&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt;))
  &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-right&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;void func(float &lt;span style=&quot;color: #666666&quot;&gt;*&lt;/span&gt;f, int len)
{
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;for&lt;/span&gt;(int i&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt;; i&lt;span style=&quot;color: #666666&quot;&gt;&amp;lt;&lt;/span&gt;len; &lt;span style=&quot;color: #666666&quot;&gt;++&lt;/span&gt;i)
        f&lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;i&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; fabsf(sinf(f&lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;i&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;*&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;8&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt;));
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-left&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;irep &lt;span style=&quot;color: #666666&quot;&gt;0x8d24b40&lt;/span&gt; nregs&lt;span style=&quot;color: #666666&quot;&gt;=5&lt;/span&gt; nlocals&lt;span style=&quot;color: #666666&quot;&gt;=3&lt;/span&gt; pools&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt; syms&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt; reps&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;file&lt;/span&gt;: tmp&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;rb
    &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;000&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;001&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R1&lt;/span&gt;:array
    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LAMBDA&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      I(&lt;span style=&quot;color: #666666&quot;&gt;+1&lt;/span&gt;)   &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;003&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SENDB&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:map&lt;/span&gt;    &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;004&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;

irep &lt;span style=&quot;color: #666666&quot;&gt;0x8d24b90&lt;/span&gt; nregs&lt;span style=&quot;color: #666666&quot;&gt;=9&lt;/span&gt; nlocals&lt;span style=&quot;color: #666666&quot;&gt;=3&lt;/span&gt; pools&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt; syms&lt;span style=&quot;color: #666666&quot;&gt;=5&lt;/span&gt; reps&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;file&lt;/span&gt;: tmp&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;rb
    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;000&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;001&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_GETCONST&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:Math&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_GETCONST&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:Math&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;003&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R1&lt;/span&gt;:x
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;004&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ADDI&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:+&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;005&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADI&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R6&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;006&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADI&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R7&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;8&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;007&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MUL&lt;/span&gt;        &lt;span style=&quot;color: #880000&quot;&gt;R6&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:*&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;008&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ADD&lt;/span&gt;        &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:+&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;009&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ADDI&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:+&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;010&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:sin&lt;/span&gt;    &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;011&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:abs&lt;/span&gt;    &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;012&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-right&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #A0A000&quot;&gt;func:&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;.LFB9:&lt;/span&gt;
    &lt;span style=&quot;color: #7D9029&quot;&gt;.cfi_startproc&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;movl&lt;/span&gt;    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt;(&lt;span style=&quot;color: #19177C&quot;&gt;%esp&lt;/span&gt;), &lt;span style=&quot;color: #19177C&quot;&gt;%ecx&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;movl&lt;/span&gt;    &lt;span style=&quot;color: #666666&quot;&gt;8&lt;/span&gt;(&lt;span style=&quot;color: #19177C&quot;&gt;%esp&lt;/span&gt;), &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;testl&lt;/span&gt;   &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;jle&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;.L1&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;movl&lt;/span&gt;    &lt;span style=&quot;color: #19177C&quot;&gt;%ecx&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;leal&lt;/span&gt;    (&lt;span style=&quot;color: #19177C&quot;&gt;%ecx&lt;/span&gt;,&lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;,&lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt;), &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;flds&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;.LC0&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;.L3:&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;fld&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;%st&lt;/span&gt;(&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;fadds&lt;/span&gt;   (&lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;fsin&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;fabs&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;fstps&lt;/span&gt;   (&lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;addl&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;$4&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;cmpl&lt;/span&gt;    &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;jne&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;.L3&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;fstp&lt;/span&gt;    &lt;span style=&quot;color: #19177C&quot;&gt;%st&lt;/span&gt;(&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;)
&lt;span style=&quot;color: #A0A000&quot;&gt;.L1:&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;ret&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The ruby VM instructions are reasonably quick, but when comparing 12 ruby
opcodes to 4 assembly instructions (fld..fstps), it&amp;#8217;s rather obvious that
there&amp;#8217;s going to be a pretty reasonable difference in speed.
MRuby isn&amp;#8217;t going to simplify any of the math that you supply it with and each
opcode (simple or not) is going to take a fair bit longer than a single assembly
instruction.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;heavy-member-access&quot;&gt;Heavy Member Access&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Accessing data stored in mruby classes isn&amp;#8217;t all that cheap even for simple
attributes.
Each member access in idiomatic ruby results in a method call via OP_SEND.
Evaluating each method call is relatively expensive compared to other opcodes
and each call tends to involve a setup phase for the arguments of each method.
In comparison for C to access member variables it&amp;#8217;s as simple as fetching memory
at an offset to the base of the structure.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-left&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #0000FF; font-weight: bold&quot;&gt;Y&lt;/span&gt;
    &lt;span style=&quot;color: #008000&quot;&gt;attr_accessor&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;:a&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;:b&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;:c&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;:d&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;

&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;func&lt;/span&gt;(array, y)
  array&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;map &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;do&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;x&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;
    x &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; y&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;a &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; y&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;b &lt;span style=&quot;color: #666666&quot;&gt;*&lt;/span&gt; y&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;c &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; y&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;d
  &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-right&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;C&quot;&gt;&lt;span&gt;&lt;/span&gt;struct Y {
    float a, b, c, d;
};

void func(float *f, int len, struct Y y)
{
    for(int i=0; i&amp;lt;len; ++i)
        f[i] = f[i] + y.a + y.b * y.c + y.d;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-left&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;irep &lt;span style=&quot;color: #666666&quot;&gt;0x94feb90&lt;/span&gt; nregs&lt;span style=&quot;color: #666666&quot;&gt;=6&lt;/span&gt; nlocals&lt;span style=&quot;color: #666666&quot;&gt;=4&lt;/span&gt; pools&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt; syms&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt; reps&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;file&lt;/span&gt;: tmp&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;rb
    &lt;span style=&quot;color: #666666&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;000&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;6&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;001&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R1&lt;/span&gt;:array
    &lt;span style=&quot;color: #666666&quot;&gt;6&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LAMBDA&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      I(&lt;span style=&quot;color: #666666&quot;&gt;+1&lt;/span&gt;)   &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;6&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;003&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SENDB&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:map&lt;/span&gt;    &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;6&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;004&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;

irep &lt;span style=&quot;color: #666666&quot;&gt;0x9510068&lt;/span&gt; nregs&lt;span style=&quot;color: #666666&quot;&gt;=7&lt;/span&gt; nlocals&lt;span style=&quot;color: #666666&quot;&gt;=3&lt;/span&gt; pools&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt; syms&lt;span style=&quot;color: #666666&quot;&gt;=6&lt;/span&gt; reps&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;file&lt;/span&gt;: tmp&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;rb
    &lt;span style=&quot;color: #666666&quot;&gt;6&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;000&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;001&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R1&lt;/span&gt;:x
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_GETUPVAR&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;       &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;003&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:a&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;004&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ADD&lt;/span&gt;        &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:+&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;005&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_GETUPVAR&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;       &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;006&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:b&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;007&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_GETUPVAR&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;       &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;008&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:c&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;009&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MUL&lt;/span&gt;        &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:*&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;010&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ADD&lt;/span&gt;        &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:+&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;011&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_GETUPVAR&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;       &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;012&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:d&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;013&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ADD&lt;/span&gt;        &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:+&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;014&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-right&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #A0A000&quot;&gt;func:&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;.LFB0:&lt;/span&gt;
    &lt;span style=&quot;color: #7D9029&quot;&gt;.cfi_startproc&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;movl&lt;/span&gt;    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt;(&lt;span style=&quot;color: #19177C&quot;&gt;%esp&lt;/span&gt;), &lt;span style=&quot;color: #19177C&quot;&gt;%ecx&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;movl&lt;/span&gt;    &lt;span style=&quot;color: #666666&quot;&gt;8&lt;/span&gt;(&lt;span style=&quot;color: #19177C&quot;&gt;%esp&lt;/span&gt;), &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;testl&lt;/span&gt;   &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;jle&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;.L1&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;flds&lt;/span&gt;    &lt;span style=&quot;color: #666666&quot;&gt;24&lt;/span&gt;(&lt;span style=&quot;color: #19177C&quot;&gt;%esp&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;fadds&lt;/span&gt;   &lt;span style=&quot;color: #666666&quot;&gt;12&lt;/span&gt;(&lt;span style=&quot;color: #19177C&quot;&gt;%esp&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;flds&lt;/span&gt;    &lt;span style=&quot;color: #666666&quot;&gt;20&lt;/span&gt;(&lt;span style=&quot;color: #19177C&quot;&gt;%esp&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;fmuls&lt;/span&gt;   &lt;span style=&quot;color: #666666&quot;&gt;16&lt;/span&gt;(&lt;span style=&quot;color: #19177C&quot;&gt;%esp&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;faddp&lt;/span&gt;   &lt;span style=&quot;color: #19177C&quot;&gt;%st&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%st&lt;/span&gt;(&lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;movl&lt;/span&gt;    &lt;span style=&quot;color: #19177C&quot;&gt;%ecx&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;leal&lt;/span&gt;    (&lt;span style=&quot;color: #19177C&quot;&gt;%ecx&lt;/span&gt;,&lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;,&lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt;), &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;.L3:&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;fld&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;%st&lt;/span&gt;(&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;fadds&lt;/span&gt;   (&lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;fstps&lt;/span&gt;   (&lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;addl&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;$4&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;cmpl&lt;/span&gt;    &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;jne&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;.L3&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;fstp&lt;/span&gt;    &lt;span style=&quot;color: #19177C&quot;&gt;%st&lt;/span&gt;(&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;)
&lt;span style=&quot;color: #A0A000&quot;&gt;.L1:&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;ret&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The mruby VM is fast, but when dealing with these member variable references the
overhead adds up.
The relatively basic loop results in a 15 opcode body.
Of those opcodes, 4 are method calls, and 4 involve setting up the method calls.
C doesn&amp;#8217;t even need a separate instruction to fetch the values due to the
addressing modes that x86 provides.
Additionally, C can recognize that the member variables are constant and
calculate their affect once outside the loop body.
That leaves 3 (fld..fstps) instructions in the loop body for a tight C loop.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;loops-of-any-sort&quot;&gt;Loops of any sort&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Actually, going one step beyond, loops over large amounts of data are just bad
for performance in MRuby due to the overhead introduced by Array#each/Array#map/etc.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-left&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$dummy&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;func&lt;/span&gt;(array)
  array&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;each &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;do&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;x&lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt;
    &lt;span style=&quot;color: #19177C&quot;&gt;$dummy&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; x
  &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-right&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;C&quot;&gt;&lt;span&gt;&lt;/span&gt;volatile int dummy;
void func(int *x, int len)
{
    for(int i=0; i&amp;lt;len; ++i)
        dummy = x[i];
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-left&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;irep &lt;span style=&quot;color: #666666&quot;&gt;0x8fa1b40&lt;/span&gt; nregs&lt;span style=&quot;color: #666666&quot;&gt;=5&lt;/span&gt; nlocals&lt;span style=&quot;color: #666666&quot;&gt;=3&lt;/span&gt; pools&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt; syms&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt; reps&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;file&lt;/span&gt;: tmp&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;rb
    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;000&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;001&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R1&lt;/span&gt;:array
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LAMBDA&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      I(&lt;span style=&quot;color: #666666&quot;&gt;+1&lt;/span&gt;)   &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;003&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SENDB&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:each&lt;/span&gt;   &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;004&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;

irep &lt;span style=&quot;color: #666666&quot;&gt;0x8fa1b90&lt;/span&gt; nregs&lt;span style=&quot;color: #666666&quot;&gt;=4&lt;/span&gt; nlocals&lt;span style=&quot;color: #666666&quot;&gt;=3&lt;/span&gt; pools&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt; syms&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt; reps&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;file&lt;/span&gt;: tmp&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;rb
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;000&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;001&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SETGLOBAL&lt;/span&gt;  :&lt;span style=&quot;color: #19177C&quot;&gt;$dummy&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R1&lt;/span&gt;:x
    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;  ; &lt;span style=&quot;color: #19177C&quot;&gt;R1&lt;/span&gt;:x&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-right&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #A0A000&quot;&gt;func:&lt;/span&gt;
    &lt;span style=&quot;color: #7D9029&quot;&gt;.cfi_startproc&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;testl&lt;/span&gt;   &lt;span style=&quot;color: #19177C&quot;&gt;%esi&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%esi&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;jle&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;.L1&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;movl&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;$0&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;.L3:&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;movl&lt;/span&gt;    (&lt;span style=&quot;color: #19177C&quot;&gt;%rdi&lt;/span&gt;,&lt;span style=&quot;color: #19177C&quot;&gt;%rax&lt;/span&gt;,&lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt;), &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;movl&lt;/span&gt;    &lt;span style=&quot;color: #19177C&quot;&gt;%edx&lt;/span&gt;, &lt;span style=&quot;color: #880000&quot;&gt;dummy&lt;/span&gt;(&lt;span style=&quot;color: #19177C&quot;&gt;%rip&lt;/span&gt;)
    &lt;span style=&quot;color: #0000FF&quot;&gt;addq&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;$1&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%rax&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;cmpl&lt;/span&gt;    &lt;span style=&quot;color: #19177C&quot;&gt;%eax&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;%esi&lt;/span&gt;
    &lt;span style=&quot;color: #0000FF&quot;&gt;jg&lt;/span&gt;  &lt;span style=&quot;color: #880000&quot;&gt;.L3&lt;/span&gt;
&lt;span style=&quot;color: #A0A000&quot;&gt;.L1:&lt;/span&gt;
    &lt;span style=&quot;color: #7D9029&quot;&gt;rep&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;ret&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In previous examples the loop overhead for C was neglected.
For this example, 3 instructions: addq, cmpl, and jg are the overhead per loop
iteration.
Ruby&amp;#8217;s is hidden in the :each method of the container.
If you&amp;#8217;re in an optimizing mindset, you might think that since :each is the
idiomatic way to build loops in ruby it would be built to limit overhead.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Nope:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #0000FF; font-weight: bold&quot;&gt;Array&lt;/span&gt;
  &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;each&lt;/span&gt;(&lt;span style=&quot;color: #666666&quot;&gt;&amp;amp;&lt;/span&gt;block)
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; to_enum &lt;span style=&quot;color: #19177C&quot;&gt;:each&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;unless&lt;/span&gt; &lt;span style=&quot;color: #008000&quot;&gt;block_given?&lt;/span&gt;

    idx, length &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;-1&lt;/span&gt;, &lt;span style=&quot;color: #008000&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;length&lt;span style=&quot;color: #666666&quot;&gt;-1&lt;/span&gt;
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;while&lt;/span&gt; idx &lt;span style=&quot;color: #666666&quot;&gt;&amp;lt;&lt;/span&gt; length &lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;and&lt;/span&gt; length &lt;span style=&quot;color: #666666&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&quot;color: #008000&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;length &lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;and&lt;/span&gt; length &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008000&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;length&lt;span style=&quot;color: #666666&quot;&gt;-1&lt;/span&gt;
      elm &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008000&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;idx &lt;span style=&quot;color: #666666&quot;&gt;+=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;1]&lt;/span&gt;
      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;unless&lt;/span&gt; elm
        &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;if&lt;/span&gt; elm&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;nil? &lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;and&lt;/span&gt; length &lt;span style=&quot;color: #666666&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&quot;color: #008000&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;length
          &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;break&lt;/span&gt;
        &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
      block&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;call(elm)
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
    &lt;span style=&quot;color: #008000&quot;&gt;self&lt;/span&gt;
  &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Translating that to VM instructions results in 25 opcodes overhead per
loop with 4 method calls (:[], :call, :length, :length).
Ouch&amp;#8230;&amp;#8203;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So, Array#each/Array#map/etc have a lot of overhead when you get to optimizing.
What about other types of loops?
A standard for loop is just an alias to :each.
A while loop however avoids much of the setup and per iteration cost.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-left&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$dummy&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;func&lt;/span&gt;(array)
  &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;for&lt;/span&gt; x &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0...&lt;/span&gt;array&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;length &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;do&lt;/span&gt;
    &lt;span style=&quot;color: #19177C&quot;&gt;$dummy&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; array&lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;x&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt;
  &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
irep &lt;span style=&quot;color: #666666&quot;&gt;0x904db40&lt;/span&gt; nregs&lt;span style=&quot;color: #666666&quot;&gt;=7&lt;/span&gt; nlocals&lt;span style=&quot;color: #666666&quot;&gt;=4&lt;/span&gt; pools&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt; syms&lt;span style=&quot;color: #666666&quot;&gt;=2&lt;/span&gt; reps&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;file&lt;/span&gt;: tmp&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;rb
    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;000&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;001&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADI&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R1&lt;/span&gt;:array
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;003&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:length&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;004&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_RANGE&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;005&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LAMBDA&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      I(&lt;span style=&quot;color: #666666&quot;&gt;+1&lt;/span&gt;)   &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;006&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SENDB&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:each&lt;/span&gt;   &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;007&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;

irep &lt;span style=&quot;color: #666666&quot;&gt;0x904db90&lt;/span&gt; nregs&lt;span style=&quot;color: #666666&quot;&gt;=5&lt;/span&gt; nlocals&lt;span style=&quot;color: #666666&quot;&gt;=1&lt;/span&gt; pools&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt; syms&lt;span style=&quot;color: #666666&quot;&gt;=2&lt;/span&gt; reps&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;file&lt;/span&gt;: tmp&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;rb
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;000&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;001&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SETUPVAR&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt;       &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_GETUPVAR&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;       &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;003&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_GETUPVAR&lt;/span&gt;   &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt;       &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;004&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:[]&lt;/span&gt;     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;005&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SETGLOBAL&lt;/span&gt;  :&lt;span style=&quot;color: #19177C&quot;&gt;$dummy&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;006&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R2&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock float-right&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$dummy&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;func2&lt;/span&gt;(array)
  itr &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
  n   &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; array&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;length
  &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;while&lt;/span&gt; itr &lt;span style=&quot;color: #666666&quot;&gt;&amp;lt;&lt;/span&gt; n
    &lt;span style=&quot;color: #19177C&quot;&gt;$dummy&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; array&lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;itr&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt;
    itr &lt;span style=&quot;color: #666666&quot;&gt;+=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
  &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;end&lt;/span&gt;
irep &lt;span style=&quot;color: #666666&quot;&gt;0x90fbb40&lt;/span&gt; nregs&lt;span style=&quot;color: #666666&quot;&gt;=8&lt;/span&gt; nlocals&lt;span style=&quot;color: #666666&quot;&gt;=5&lt;/span&gt; pools&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt; syms&lt;span style=&quot;color: #666666&quot;&gt;=5&lt;/span&gt; reps&lt;span style=&quot;color: #666666&quot;&gt;=0&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;file&lt;/span&gt;: tmp&lt;span style=&quot;color: #666666&quot;&gt;.&lt;/span&gt;rb
    &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;000&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ENTER&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;:&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;001&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADI&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;               ; &lt;span style=&quot;color: #19177C&quot;&gt;R3&lt;/span&gt;:itr
    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;002&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R1&lt;/span&gt;:array
    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;003&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:length&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;004&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R4&lt;/span&gt;:n
    &lt;span style=&quot;color: #666666&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;005&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_JMP&lt;/span&gt;                &lt;span style=&quot;color: #666666&quot;&gt;013&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;6&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;006&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R1&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R1&lt;/span&gt;:array
    &lt;span style=&quot;color: #666666&quot;&gt;6&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;007&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R6&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R3&lt;/span&gt;:itr
    &lt;span style=&quot;color: #666666&quot;&gt;6&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;008&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SEND&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:[]&lt;/span&gt;     &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;6&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;009&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_SETGLOBAL&lt;/span&gt;  :&lt;span style=&quot;color: #19177C&quot;&gt;$dummy&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;010&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R3&lt;/span&gt;:itr
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;011&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_ADDI&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:+&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;7&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;012&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R3&lt;/span&gt;:itr
    &lt;span style=&quot;color: #666666&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;013&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R3&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R3&lt;/span&gt;:itr
    &lt;span style=&quot;color: #666666&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;014&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_MOVE&lt;/span&gt;       &lt;span style=&quot;color: #880000&quot;&gt;R6&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R4&lt;/span&gt;              ; &lt;span style=&quot;color: #19177C&quot;&gt;R4&lt;/span&gt;:n
    &lt;span style=&quot;color: #666666&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;015&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LT&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #19177C&quot;&gt;:&amp;lt;&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;016&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_JMPIF&lt;/span&gt;      &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #666666&quot;&gt;006&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;017&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_LOADNIL&lt;/span&gt;    &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;018&lt;/span&gt; &lt;span style=&quot;color: #880000&quot;&gt;OP_RETURN&lt;/span&gt;     &lt;span style=&quot;color: #880000&quot;&gt;R5&lt;/span&gt;      &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;There&amp;#8217;s still plenty of register shuffling with the while loop, but 6-7 opcodes
of overhead per iteration and only one method call (:[]) sure beats 25 extra
opcodes per loop.
So, if you want to keep a hotspot in pure ruby, you might have more luck with
inlining a while loop or using :each_index which is a middle ground in terms of
cost.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;MRuby is reasonably fast, though once you&amp;#8217;re ploughing through enough data and
code, then hotspots slowing things down are basically inevitable.
MRuby makes it pretty easy to patch up these hotspots by seamlessly
implementing the methods in C.
To keep a codebase quick you still need to find hotspots in code and tools like
mruby-prof make this task a &lt;strong&gt;lot&lt;/strong&gt; easier.
I hope this ramble about using mruby-profiler is helpful.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Tue, 14 Feb 2017 00:00:00 -0500</pubDate>
        <link>http://log.fundamental-code.com/2017/02/14/profiling-mruby.html</link>
        <guid isPermaLink="true">http://log.fundamental-code.com/2017/02/14/profiling-mruby.html</guid>
        
        
      </item>
    
  </channel>
</rss>
