In this lesson, you will learn how to design high-performance systems that scale linearly with your hardware by eliminating cross-thread contention.
The Problem with Shared-State Concurrency
In typical async runtimes, you have a global task queue. When multiple CPU cores compete to pull tasks from this shared queue, they must synchronize via atomic operations (like compare_and_swap). As your core count grows, the cost of managing this shared state causes performance to plateau or even degrade—a phenomenon known as contention overhead.
The Thread-Per-Core Philosophy
A "Thread-Per-Core" architecture abandons the global queue. Instead, it pins one dedicated executor instance to each physical CPU core. Each executor maintains its own private, local task queue.
By ensuring that tasks never "migrate" across threads, you eliminate the need for cross-thread synchronization primitives like Mutex or Arc for task coordination. Since a task is always processed on the same core, you also maximize CPU L1/L2 cache hits, as data remains "warm" on the specific core that owns that task.
Conceptual Implementation
Instead of a global spawn function that pushes to a shared pool, you interact with a specific shard:
// Conceptual shard-local executor
let shard = executor_per_core.get_current_shard();
// Because the executor is pinned to the core,
// no cross-thread lock is required to push this task.
shard.spawn(async move {
// This task will only ever run on this core.
process_data().await;
});
To make this effective, your application logic must be shard-aware. If you are building a database or a network server, you partition your input data (e.g., based on a user ID hash) so that all requests for a specific resource are routed to the same core. This turns a complex multi-threaded synchronization problem into a series of independent, single-threaded problems. When cores don't need to talk to each other, they don't wait for each other, allowing your throughput to scale linearly with every CPU core you add.
Key Takeaway: Thread-per-core architectures achieve peak performance by pinning tasks to specific cores, eliminating contention on shared queues and maximizing data locality.