In this series we’ll understand and learn how to compute, quantify and, measure the performance of different systems and programs.
To compute, quantify and, measure performance let’s start by first defining what performance depends on.
Performance dependencies
When we’re making a system or a program a lot of different factors will weigh in the total performance:
-
The underlying algorithm
- Determines number of operations required, which directly impacts the performance.
-
Programming language, compile, and, architecture of choice.
- Determines number of instructions.
-
Processor and memory
- Determines how quickly each instruction executes
-
I/O System (Includes the OS)
- Determines how quickly each I/O operation executes
CPU Time
We can define CPU time by a very nice equation: $$ \text{CPU Time} = \frac{\text{Instructions}}{\text{Program}} \cdot\ \frac{\text{Clock cycles}}{\text{Instruction}} \cdot\ \frac{\text{Seconds}}{\text{Clock cycle}} $$
We will call these as the following: $$ \text{CPU Time} = IC \cdot\ CPI \cdot\ T_c $$
One way to actually then measure computers or programs is using SPEC.
SPEC, or Standard Performance Evaluation Corp, is a company which specialize in measuring.
The idea is to normalize compared to a reference computer using geometric means.
This is called the SPECvalue.
Geometric mean: $$ \sqrt[n]{\prod_{i = 1}^{n} \text{Execution time ratio}_i} $$
RISC/CISC Architecture
In the early days, it was thought that, if we made the machine instructions closer to real (higher-level) programming functions, it would be faster for the computer.
We now know this is not true, and machine instructions are therefore as small and atomic as possible. These two approaches are known as RISC and CISC.
- RISC (Reduced Instruction Set Computers)
- CISC (Complex Instruction Set Computers)
MIPS
In this series we will use a MIPS instruction set, MIPS is still used widely in the real world, but it’s slowly fading away to due RISC V’s popularity.
Let’s see some MIPS operations:
Arithmetic operations
add a, b, c # a := b + cAll arithmetic operations have this form, two source register and one destination registers.
We also see that comments are denoted by a # in MIPS programs.
Register operations
All operations in assembly languages utilize registers.
MIPS has a 32 x 32 bit register file (RF)
They are numbered 0 to 31 and, just a refresher, 32-bit data is called a “word”.
Example:
f = (g + h) - (i + j);Given that $f, \ldots, j$ are in registers $s_0, \ldots, s_4$, in MIPS this will become:
add $t0, $s1, $s2 # temp0 := g + hadd $t1, $s3, $s4 # temp1 := i + jsub $s0, $t0, $t1 # f := t0 - t1Memory operations
Since MIPS is byte addressable, it means that each “word” has 4 bytes. Also good to note here is that MIPS uses big endian
Example:
g = h + A[8];Given that g is in $s_1$, h in $s_2$ and, the starting address for A is at $s_3$
We will get the following MIPS code:
lw $t0, 32($s3) # load wordadd $s1, $s2, $t0Example 2:
A[12] = h + A[8];Given that h is in $s_2$, and, the starting address for A is at $s_3$
lw $t0, 32($s3) # load wordadd $t0, $s2, $t0sw $t0, 48($s3) # store wordImmediate operations
Instead of, for example, adding two registers, we may just want to add a constant, this can be done via:
addi $s3, $s3, 4For subtracting we just do:
addi $s2, $s1, -1Zero register
In MIPS there is a hard-coded zero register, that always contains the value zero, this can be used to quickly move values between registers:
add $t2, $s1, $zero # t2 := s1Logical operations
In MIPS there are of course logical operations:
# Logical Shiftssll $t0, $t1, 2 # t0 := t1 * 4srl $t0, $t1, 2 # t0 := t1 / 4
# Logical ANDand $t0, $t1, $t2 # t0 := t1 & t2andi $t0, $t1, 2 # t0 := t1 & 2
# Logical ORor $t0, $t1, $t2 # t0 := t1 | t2ori $t0, $t1, 2 # t0 := t1 | 2
# Logical NOTnor $t0, $t1, $zero # := NOT(t1)Notice there isn’t an explicit not operation, but rather we use a nor operation with the zero register.
Conditional jumps
In MIPS there is only two conditional jumps, beq and bne:
beq rs, rt, L1 # if(rs == rt); Jump to L1bne rs, rt, L1 # if(rs != rt); Jump to L1j L1 # Jump to L1So for example the following C-code:
if(i == j) { f = g + h;} else { f = g - h;}Given that $f, g, \ldots$ is in $s_0, s_1, \ldots$
MIPS:
bne $s3, $s4, Else # if(i == j) jump to Elseadd $s0, $s1, $s2 # f = g + hj Exit # Jump to exit
Else: sub $s0, $s1, $s2 # f = g - hExit: ...Notice how there isn’t any usual blt, bge, since MIPS is of RISC architecture, we don’t need those.
Instead, what we can do is using slt. Which stands for set less than, we can now use this to replicate a blt or bge.
However, blt, bge are still pseudo-keywords in MIPS. The assembler will still be able to interpret these.
On the topic of pseudo-keywords, things like move and li are also pseudo-keywords.