How do we go from a truth table to the leanest Boolean expression? We show three paths: the canonical forms with minterms and maxterms, algebraic simplification, and the Karnaugh map, with worked exercises and a check in Python with SymPy.
Every operation of a processor can be described with three logical operations: AND, OR and NOT. We go from gates and truth tables to theorems, De Morgan’s laws and the simplification of expressions, with the half adder as the first circuit and examples in Python.
With 10% serial code, eight cores make the program only 4.7 times faster, and no number of cores gets past 10 times. We close the series with RISC and CISC, performance metrics, Flynn’s taxonomy, SMP, clusters, NUMA, multicore, and Amdahl’s Law.
Busy-waiting on a 10 ms disk, a 1 GHz CPU wastes ten million cycles. We compare the three ways of handling input and output (polling, interrupts, and DMA), calculate the overhead of each one, and see why polling came back with NVMe SSDs.
Python does not run your code line by line: first, CPython compiles it to bytecode. With the tokenize, ast, compile, and dis modules, we follow a simple expression from tokens to syntax tree to bytecode, right in the interpreter.
You write a line of code, and the processor only understands bits. We follow the translation: the two-pass assembler, the compiler phases, linking and loading. Along the way, GCC cuts twelve instructions down to two with -O2, and we see where Python and Java sit between compiling and interpreting.
The same expression costs 5 instructions with three operands, 7 with two, and 11 with an accumulator. We will see the ISA, the contract between hardware and software, instruction formats, the RISC-V R-type, and the seven addressing modes that tell where each operand is.
Uppercase and lowercase differ by a single bit in the ASCII table, and that was no accident. To the hardware everything is bits, and the value depends on the reading convention: ASCII, Unicode, and UTF-8 for text, two’s complement for integers, and IEEE 754 for real numbers.
An assembly line does not wait for one car to be finished before starting the next, and the pipeline does the same with instructions. We will see the stages, the hazards that stall the line, the speedup calculation, the buses that connect CPU, memory, and peripherals, and the control unit.
A hypothetical 12-bit processor with 15 instructions serves as a model for following the complete instruction cycle. We execute LDA and ADD register by register, encode instructions in hexadecimal, and write assembly programs with branches and loops.
A 2 GHz processor can execute more instructions per second than a 3 GHz one. To understand why, we open up the CPU: ALU, control unit, registers, flags, decoder, and clock, along with the microevents of the fetch cycle in formal notation.
With a 95% hit rate, the cache makes the processor see a 4.95 ns memory where DRAM takes 80 ns. We will see why it works (locality), the direct, associative, and set-associative mappings, the replacement algorithms, and the write policies.
If a register access took one second, a main memory access would take four and a half minutes, and a hard disk access, more than a year. We will see the memory hierarchy, cells, addresses and buses, the sizing formulas, and SRAM, DRAM, ROM and ECC.
You press Enter and the result shows up three tenths of a second later. In that interval, the processor fetched hundreds of millions of instructions from memory. This series of 13 articles explains how: memory, cache, CPU, pipeline, data representation, and program execution.