Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[server] Consider breaking message handling into a three-stage pipeline #69

Open
jamesmunns opened this issue Dec 19, 2024 · 0 comments

Comments

@jamesmunns
Copy link
Owner

jamesmunns commented Dec 19, 2024

While experimenting with USB benchmarking, I realized that there was a significant performance bump when switching from "receive then transmit" to "receive in one task, hand data off to other task, other task sends". postcard-rpc currently does all of the following in one task:

  • Receive bytes off the wire
  • Buffer them into a frame
  • When a frame is complete, attempt to deserialize
  • if deserialize succeeds, attempt to dispatch
  • if dispatching succeeds, attempt to serialize the response
  • if serializing succeeds, send the response frame one packet at a time

We would likely see some improvement by breaking the process into three stages:

  • One that handles buffering of an entire frame
  • One that does deser, dispatch, ser
  • One that does fragmentation and sending of the frame as parts

IMO this would be a very good use case for a pair of bbqueue or bbq2, as it is already async, sharable, and offers a framed interface. This would allow receiving to not be blocked by the relatively larger middle steps, as well as the time it takes to respond. Data can also be received directly into and out of the bbqueue, meaning that we do not pay any extra copying costs when sending frames between the pipelined stages.

Here are the graphs from testing simple bulk frame loopback using first just a single task:

Screenshot 2024-12-20 at 10 51 04

And here's what it looks like when I used a basic embassy-sync channel to split sending and receiving into separate tasks:

Screenshot 2024-12-19 at 16 37 10

We should keep an eye on how much complexity this adds, and may be able to be handled transparently in the server stack by instead implementing the WireRx and WireTx traits using bbqueue handles instead of directly driving the USB endpoints. This may also be useful for other protocols as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant