3 ms·
What if you have to map accept, read, write & close (so four types of tasks) to a six cores? ;-) Yes, nginx & varnish have different approaches. Their approach
by cbsmith 11y ago
What if you have to map accept, read, write & close (so four types of tasks) to a six cores? ;-)
Yes, nginx & varnish have different approaches. Their approaches tend to work better for their type of application.
One thread or process per core, with its own event loop, is indeed a very standard pattern. The process-per-core style approaches tend to shard per fd (e.g., nginx), while the thread-per-core style tend to either shard by IO request or don't shard at all (each thread has an independent poll of all outstanding IOs). Particularly if you use a continuations style paradigm, it makes it really easy to convert over existing code to the design.
In practice, you will typically have better cache locality with the fd than your position in the state machine (and the model you are describing isn't quite where you are in the state machine, but you can adjust it to fit). If your state machine is simple enough, your approach might get better instruction cache hit rate, but you are basically guaranteeing that data has to move between the processor caches in very rapid succession. In practice, not only are you forcing the fd's to be passed between processor caches, but there tends to be data locality with that fd. While it is easy to have the instruction cache replicated across all processors, the data mutates quite rapidly. Again, this stuff is covered in the discussions on the c10k site.