System Calls and Context Switches
Why a trading program asking the operating system to do something — read a socket, write a file — is far slower than doing pure computation, and why switching between tasks on a CPU carries a hidden tax.
A CPU spends most of its time running your program's own instructions, but the moment your code needs something only the operating system can provide — reading a network packet, writing to disk, asking for the time — it makes a system call, handing control to the kernel. That handoff isn't free. The CPU has to save the program's current state, switch into a more privileged mode, run kernel code, then switch back. On a low-latency trading system, where the whole strategy loop might target single-digit microseconds, a single system call can cost more than the entire rest of the loop.
A context switch is the related, more general cost: whenever the CPU stops running one task and starts running another — whether that's the kernel taking over during a system call, or the operating system moving to a completely different process — it must save the paused task's registers and reload the new one's, and it typically loses the contents of the CPU's fast cache memory that had been "warmed up" for the paused task. That cache has to refill from scratch, which is often the more expensive part.
Worked example
Suppose a market-data handler processes a packet in 200 nanoseconds of pure computation, but each packet arrives via a socket read that triggers a system call costing 1,500 nanoseconds of kernel overhead. Handling one packet costs roughly 1,700 nanoseconds total — the system call is nearly 90% of the cost, not the actual processing. This is why high-performance trading systems go to great lengths to avoid system calls in the hot path, for example by polling a shared memory region the kernel writes to directly instead of calling read() for every packet.
System calls and context switches are the hidden tax on "asking the operating system for something" — the overhead of saving and restoring CPU state and refilling caches often dwarfs the actual work being done, which is why latency-sensitive trading code tries to minimize how often it crosses into kernel mode.
Related concepts
Practice in interviews
Further reading
- Gorman, Understanding the Linux Virtual Memory Manager