4 ms·
The question to ask is: Can you do better? Say you use a state machine instead of using coroutines. Will one state transition of the machine be faster than one
by rumcajz 10y ago
The question to ask is: Can you do better?
Say you use a state machine instead of using coroutines. Will one state transition of the machine be faster than one context switch?
180ns can definitely be improved on (with the C implementation in the project it's more likely to be 60ns or so) there's no fundamental reason why one approach should be faster than the other, given that both are doing basically the same thing, albeit on the different layers of the stack.
- tmyklebu 10y agoI'm not clear on why coroutines or an explicit state machine are necessary to implement network protocols. We have been doing it for decades by writing straightforward imperative C code and for years by writing C++ template classes that are templated on the downstream type (CRTP). Both of these approaches result in near-zero overhead (computers are good at fetching and decoding consecutive instructions) or even negative apparent overhead (if the compiler sees caller and callee, inlining and dead code elimination can potentially eliminate lower-level protocol handling irrelevant to the higher-level protocol). I would guess that transforming coroutine-based code into state machines hampers performance over the long term by scaring the programmer away from wanting to touch it. However, I would also guess that the direct cost of a coroutine context switch (save and restore all callee-save registers and stack pointer then indirect-jump somewhere unpredictable) outweighs the direct cost of a state machine transition (update some variable). I do not want to pass judgment on the approach beyond saying that its attendant overhead is too high for some workloads.
- rumcajz 10y agoOk, but doesn't "straight imperative code" rely on blocking API underneath it? If it does not, the implementation has to store the current state in case it cannot proceed immediately, then restore it later -- which is a context switch. As for state machine vs. coroutine performance, agreed. But the cost is somewhere around 10-15ns per context switch. Which may be worth paying to get a maintainable code.
- tmyklebu 10y agoYou can use the usual BSD socket API (in which case the context switches to/from the kernel for calling read() puts the contemplated workload out of reach) or any number of vendor-specific userland network stacks. There is no need to context switch. (Function calls and function returns are not context switches.)