Chapter 10: Robot Computing and Embedded Systems

Lesson 1: Microcontrollers vs. CPUs vs. GPUs

Robots are cyber–physical systems: sensors and actuators interact with the physical world while computation closes the loop. This lesson builds a rigorous, hardware-level view of three core compute classes used in robots—microcontrollers (MCUs), central processing units (CPUs), and graphics processing units (GPUs)—and compares them through timing, parallelism, memory hierarchy, and energy models. We emphasize quantitative reasoning for selecting compute for control, perception, and planning tasks.

1. Conceptual Overview

A robot typically needs: (i) tight-loop control at high sampling rate, (ii) mid-level state estimation and sensor processing, (iii) heavy parallel workloads such as vision or learning. These map naturally to different compute devices.

flowchart TD
  S["Sensors / Actuators"] --> M["MCU: tight I/O + hard timing"]
  M --> C["CPU: general-purpose compute"]
  C --> G["GPU: massive data-parallel compute"]
  M -->|fast buses| C
  C -->|high-bandwidth links| G
  G --> C --> M
        

We will compare devices using four quantitative lenses: latency (how fast a single task finishes), throughput (how many tasks per second), determinism (timing variability), and energy per operation.

2. Architectural Models

2.1 Microcontrollers (MCUs)

MCUs integrate CPU core(s), flash, SRAM, timers, ADC/DAC, PWM, and peripheral buses on a single chip. They are designed for direct I/O, low power, and predictable execution. Common properties:

  • Small on-chip memory, often no cache or small cache.
  • No virtual memory; code executes from flash.
  • Interrupt-driven control and communication.
  • Clock frequencies typically in tens–hundreds of MHz.

2.2 CPUs

CPUs target low-latency sequential performance for diverse programs: deep cache hierarchies, branch prediction, out-of-order execution, SIMD vector units, and virtual memory. Properties:

  • Large RAM, multi-level caches (L1/L2/L3).
  • Complex instruction pipelines to maximize IPC.
  • Often run a full OS (Linux/RTOS).
  • Clock frequencies in GHz range.

2.3 GPUs

GPUs sacrifice single-thread latency to maximize throughput using thousands of lightweight threads and very high memory bandwidth. Key model: single-instruction multiple-thread (SIMT). Properties:

  • Many streaming multiprocessors (SMs) each running thread warps.
  • High bandwidth global memory + fast shared memory.
  • Efficient for dense linear algebra and convolution-like tasks.

3. Timing and Performance Mathematics

3.1 Basic Execution-Time Model

For a program with \( N_{\text{inst}} \) instructions, average cycles-per-instruction \( \text{CPI} \), and clock frequency \( f \), execution time is

\[ T \;=\; \frac{N_{\text{inst}} \cdot \text{CPI}}{f}. \]

MCUs typically have small, stable CPI (simple pipelines), while CPUs have lower average CPI but higher variability due to caches and speculation. GPUs expose different units: we model throughput rather than CPI.

3.2 Throughput and Parallel Speedup

Suppose a workload has a fraction \( p \) that is perfectly parallelizable and fraction \( 1-p \) that is inherently serial. With \( n \) parallel workers, the ideal time is

\[ T(n) \;=\; T_1 \big( (1-p) + \frac{p}{n} \big), \quad S(n) \;=\; \frac{T_1}{T(n)} \;=\; \frac{1}{(1-p)+\frac{p}{n}}. \]

Proof (Amdahl's Law):

Let the serial part take time \( T_s = (1-p)T_1 \) and the parallel part take \( T_p = pT_1 \). Under perfect load balance, each worker executes \( T_p/n \). Hence total time is \( T(n)=T_s+T_p/n \), giving the speedup above. As \( n \to \infty \),

\[ \lim_{n\to\infty} S(n) \;=\; \frac{1}{1-p}, \]

so GPUs help only when \( p \approx 1 \). Many perception tasks satisfy this; tight control loops usually do not.

3.3 Memory-Bound vs Compute-Bound (Roofline View)

Let a kernel perform \( F \) floating-point operations (FLOPs) and move \( B \) bytes from memory. Define arithmetic intensity \( I = F/B \). If peak compute is \( P_{\max} \) (FLOPs/s) and memory bandwidth is \( \beta \) (bytes/s), achievable performance is bounded by

\[ P \;\le\; \min\big(P_{\max},\; \beta I\big). \]

CPUs often operate near compute-bound for small matrix tasks (high cache reuse), while GPUs excel for high-intensity kernels (GEMM, convolution). MCUs are usually bandwidth-limited due to tiny SRAM and flash latency.

3.4 Determinism as Variance of Timing

For periodic robot tasks, we care not only about mean time \( \mu_T \) but also jitter (variance) \( \sigma_T^2 \). Model task execution times \( T_k \) as i.i.d. samples:

\[ \mu_T = \mathbb{E}[T_k], \qquad \sigma_T^2 = \mathbb{E}\big[(T_k-\mu_T)^2\big]. \]

MCUs aim for small \( \sigma_T^2 \) (predictable pipelines, no caches). CPUs and especially GPUs may show larger jitter because cache misses, OS scheduling, and memory contention create long-tail delays.

4. Energy and Power Models

Robot platforms are power-constrained. A simple CMOS dynamic power model is

\[ P_{\text{dyn}} = \alpha C V^2 f, \]

where \( \alpha \) is switching activity, \( C \) effective capacitance, \( V \) supply voltage, and \( f \) frequency. With execution time \( T \), dynamic energy is

\[ E_{\text{dyn}} = P_{\text{dyn}} T. \]

MCUs reduce \( V \) and \( f \) aggressively, giving small \( E_{\text{dyn}} \) per operation. GPUs increase \( \alpha \) and \( C \) by using many cores, but can reduce energy per FLOP for highly parallel workloads because the same work finishes in much smaller \( T \).

A useful selection metric is energy per useful operation: if a task needs \( F \) operations,

\[ \varepsilon = \frac{E}{F} \quad \text{[J/op]}. \]

In robots, MCUs minimize \( \varepsilon \) for simple control and I/O, CPUs for mixed workloads, GPUs for high-FLOP parallel tasks.

5. Mapping Robot Workloads to Hardware

Given a periodic control loop with sampling period \( h \), the computation must complete within \( h \). Let compute time on device d be \( T_d \). Feasibility requires

\[ T_d \;\le\; h. \]

If the loop also has sensor I/O latency \( L_{\text{io}} \), then total budget is

\[ T_d + L_{\text{io}} \;\le\; h. \]

High-rate motor control (kHz) typically yields small \( h \), favoring MCUs directly connected to PWM/encoders. State estimation at tens–hundreds of Hz and decision logic benefit from CPU flexibility. Dense perception (images, point clouds) and learning are near-parallel with large \( p \) and high arithmetic intensity, favoring GPUs.

flowchart TD
  CTRL["Control loops (kHz)"] --> MCU["MCU"]
  EST["Filtering / estimation (10-200 Hz)"] --> CPU["CPU"]
  PER["Vision / learning / dense geometry"] --> GPU["GPU"]
  MCU --> CPU --> GPU
  GPU --> CPU --> MCU
        

6. Multi-language Computational Examples

We illustrate the same control-oriented computation executed in styles aligned with each device. Consider a discrete-time state update and control law (students know linear control):

\[ \mathbf{x}_{k+1} = \mathbf{A}\mathbf{x}_k + \mathbf{B}\mathbf{u}_k,\qquad \mathbf{u}_k = -\mathbf{K}\mathbf{x}_k. \]

We compare (i) MCU-style fixed-point update, (ii) CPU-style double precision, (iii) GPU-style batch-parallel updates.

6.1 Python (CPU baseline with NumPy)


import numpy as np

A = np.array([[1.0, 0.01],
              [0.0, 1.0]])
B = np.array([[0.0],
              [0.01]])
K = np.array([[2.0, 0.5]])

x = np.array([[0.1],
              [0.0]])

def step(x):
    u = -K @ x
    return A @ x + B @ u

for k in range(1000):
    x = step(x)
print(x.ravel())
      

Libraries often used on CPUs for robotics math include NumPy/SciPy (linear algebra, filtering), and JAX/PyTorch (accelerated tensor compute), but here we stay with pure NumPy.

6.2 C++ (CPU with Eigen)


#include <iostream>
#include <Eigen/Dense>

int main() {
  Eigen::Matrix2d A;
  A << 1.0, 0.01,
       0.0, 1.0;
  Eigen::Vector2d B;
  B << 0.0, 0.01;
  Eigen::RowVector2d K;
  K << 2.0, 0.5;

  Eigen::Vector2d x(0.1, 0.0);

  for (int k = 0; k < 1000; ++k) {
    double u = -(K * x)(0);
    x = A * x + B * u;
  }
  std::cout << x.transpose() << std::endl;
  return 0;
}
      

Eigen and BLAS/LAPACK backends are standard CPU-side numerical tools in robotics.

6.3 Java (CPU with EJML)


import org.ejml.simple.SimpleMatrix;

public class LQRStep {
    public static void main(String[] args) {
        SimpleMatrix A = new SimpleMatrix(new double[][]{
            {1.0, 0.01},
            {0.0, 1.0}
        });
        SimpleMatrix B = new SimpleMatrix(new double[][]{
            {0.0},
            {0.01}
        });
        SimpleMatrix K = new SimpleMatrix(new double[][]{
            {2.0, 0.5}
        });

        SimpleMatrix x = new SimpleMatrix(new double[][]{
            {0.1},
            {0.0}
        });

        for(int k=0;k<1000;k++){
            SimpleMatrix u = K.mult(x).scale(-1.0);
            x = A.mult(x).plus(B.mult(u));
        }
        System.out.println(x);
    }
}
      

EJML provides efficient matrix routines in pure Java, suitable for CPU-based robot code.

6.4 MATLAB / Simulink (CPU, script + block mapping)


A = [1 0.01; 0 1];
B = [0; 0.01];
K = [2 0.5];
x = [0.1; 0];

for k = 1:1000
    u = -K*x;
    x = A*x + B*u;
end
disp(x)
      

In Simulink, the same update is a loop of blocks: a Matrix Gain for \( \mathbf{K} \), Sum blocks for addition, and Unit Delay for \( \mathbf{x}_k \). Simulink Coder can generate embedded C for MCU targets.

6.5 MCU-style Fixed-Point (illustrative embedded C subset)

MCUs often avoid floating-point. Let fixed-point scale be \( s = 2^q \). We represent \( \hat{x} = \lfloor s x \rceil \). A multiply-accumulate approximates \( y = ab \) by \( \hat{y} = (\hat{a}\hat{b})/s \).


// Fixed-point Qq format example (for MCUs without FPU)
#include <stdint.h>

#define Q 12
#define SCALE (1<<Q)

int32_t fx_mul(int32_t a, int32_t b){
    return (int32_t)(((int64_t)a * b) >> Q);
}

// Example 2x2 state update with fixed-point
void step_fx(int32_t x1, int32_t x2,
             int32_t* nx1, int32_t* nx2){
    // A = [[1, dt],[0,1]], B=[[0],[dt]]
    const int32_t dt = (int32_t)(0.01 * SCALE);
    const int32_t k1 = (int32_t)(2.0  * SCALE);
    const int32_t k2 = (int32_t)(0.5  * SCALE);

    int32_t u = -(fx_mul(k1, x1) + fx_mul(k2, x2));
    *nx1 = x1 + fx_mul(dt, x2);          // x1 + dt*x2
    *nx2 = x2 + fx_mul(dt, u);           // x2 + dt*u
}
      

The MCU approach prioritizes predictable timing and low energy, at the cost of precision.

6.6 GPU-style Batch Update (conceptual Python with CuPy)

GPUs are useful when updating many states in parallel (e.g., particles, pixels, or multiple robots). A minimal GPU-side version uses CuPy:


# Requires a CUDA-capable GPU and cupy installed
import cupy as cp

A = cp.array([[1.0, 0.01],
              [0.0, 1.0]])
B = cp.array([[0.0],
              [0.01]])
K = cp.array([[2.0, 0.5]])

# Batch of N states (2 x N)
N = 100000
x = cp.random.randn(2, N) * 0.1

for k in range(1000):
    u = -(K @ x)              # 1 x N
    x = A @ x + B @ u         # 2 x N
cp.cuda.Stream.null.synchronize()
print(cp.mean(x, axis=1))
      

CuPy mirrors NumPy syntax but dispatches to GPU kernels. Similar roles are played by CUDA C++, OpenCL, or Vulkan compute.

7. Problems and Solutions

Problem 1 (Speedup Bound): A perception pipeline has a parallelizable fraction \( p=0.92 \). (a) Compute the ideal speedup for \( n=64 \) GPU workers. (b) Compute the maximum possible speedup as \( n \to \infty \).

Solution:

\[ S(64) = \frac{1}{(1-0.92)+\frac{0.92}{64}} = \frac{1}{0.08+0.014375} \approx 10.60. \]

\[ S(\infty)=\frac{1}{1-p}=\frac{1}{0.08}=12.5. \]

Even huge GPUs cannot exceed 12.5× due to the serial bottleneck.

Problem 2 (Compute vs Memory Bound): A kernel performs \( F=2\times10^9 \) FLOPs and moves \( B=4\times10^8 \) bytes. A CPU has \( P_{\max}=5\times10^{11} \) FLOPs/s and \( \beta=5\times10^{10} \) bytes/s. Is the kernel compute-bound or memory-bound? What is the bound on performance?

Solution:

\[ I = \frac{F}{B} = \frac{2\times10^9}{4\times10^8} = 5 \;\text{FLOPs/byte}. \]

\[ \beta I = (5\times10^{10})\cdot 5 = 2.5\times10^{11}\;\text{FLOPs/s}. \]

Since \( \beta I < P_{\max} \), the kernel is memory-bound and \( P \le 2.5\times10^{11} \) FLOPs/s.

Problem 3 (Fixed-Point Quantization Error): A scalar state update uses fixed-point with scale \( s=2^q \). Show that the quantization error \( e = x - \hat{x}/s \) satisfies \( |e| \le 1/(2s) \).

Solution:

By definition, \( \hat{x} = \lfloor s x \rceil \) is rounding to the nearest integer. Therefore \( |s x - \hat{x}| \le 1/2 \). Divide by \( s \):

\[ \left|x-\frac{\hat{x}}{s}\right| \le \frac{1}{2s}. \]

Problem 4 (Control-Loop Feasibility): A motor controller runs at \( h=1\text{ ms} \). Sensor I/O takes \( L_{\text{io}}=0.25\text{ ms} \). (a) What is the maximum allowed compute time? (b) If an MCU implementation takes \( 0.6\text{ ms} \) and a CPU implementation takes \( 0.3\text{ ms} \) but with jitter standard deviation \( \sigma_T = 0.2\text{ ms} \), which is safer for timing?

Solution:

\[ T_d \le h - L_{\text{io}} = 1 - 0.25 = 0.75\text{ ms}. \]

(a) Any compute below 0.75 ms is feasible in mean. (b) MCU mean 0.6 ms with low jitter stays safely below 0.75 ms. CPU mean 0.3 ms is smaller, but a 3-sigma worst case is \( 0.3 + 3(0.2)=0.9\text{ ms} > 0.75\text{ ms} \). Hence the MCU is safer for strict periodic timing.

8. Summary

We modeled and compared MCUs, CPUs, and GPUs using execution-time, parallel speedup, memory–compute bounds, determinism, and energy. MCUs deliver predictable low-power I/O-centric compute for high-rate control; CPUs provide flexible low-latency general computation; GPUs provide throughput for highly parallel, arithmetic-intensive tasks. These quantitative tools will support real-time and interface discussions in the next lessons.

9. References

  1. Amdahl, G.M. (1967). Validity of the single processor approach to achieving large scale computing capabilities. AFIPS Conference Proceedings, 30, 483–485.
  2. Hennessy, J.L., & Patterson, D.A. (2019). A new golden age for computer architecture. Communications of the ACM, 62(2), 48–60.
  3. Jouppi, N.P., et al. (2017). In-datacenter performance analysis of a tensor processing unit. Proceedings of ISCA, 1–12.
  4. Williams, S., Waterman, A., & Patterson, D.A. (2009). Roofline: An insightful visual performance model for multicore architectures. Communications of the ACM, 52(4), 65–76.
  5. Lee, E.A. (2008). Cyber physical systems: Design challenges. Proceedings of ISORC, 363–369.
  6. Buttazzo, G. (2011). Research trends in real-time computing for embedded systems. ACM SIGBED Review, 8(1), 3–6.
  7. Owczarek, P., & Toth, A. (2020). Deterministic execution on embedded processors: A survey. ACM Computing Surveys, 53(4), 1–36.