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

Discussion: Implement an HTTP server using C++ 20 coroutines and io_uring #2

Open
xiaoyang-sde opened this issue Apr 28, 2023 · 3 comments
Assignees

Comments

@xiaoyang-sde
Copy link
Owner

Feel free to share thoughts, ideas, and suggestions.

@xiaoyang-sde xiaoyang-sde self-assigned this Apr 28, 2023
@xiaoyang-sde xiaoyang-sde pinned this issue Apr 28, 2023
@CarterLi
Copy link

CarterLi commented May 5, 2023

之前研究过一点io-uring

  • 有个小问题:multishot_accept 是怎么使用的没看懂。就我所知一个 multishot_sqe 会有多个 cqe,所有 cqe 的 data 都是一样的,这就和 coroutine 使用冲突,因为每次 resume 之后 coroutine address 都已经变了。

  • 还有一些小建议:

  1. 别用 splice。io-uring 目前版本的 splice 极其慢,比 read-send 慢很多
  2. 可以使用 IOLINK 减少 syscall 次数,比如 read(IOLINK)-send。这两个请求一次性 submit,send 会等待 read 执行成功后再执行。
  3. 建议使用同步版本的 cancel。异步的 cancel 不能保证IO请求被及时取消,导致 use-after-free 的情况
  4. 少用 std::function。std::function 会动态申请内存并有类型擦除机制,比直接调用函数慢很多。建议 io_uring::for_each_cqe 改成返回迭代器,这样既可以避免回调函数省去 std::function,而且普通循环更容易使用可以随时 break
  5. cqe_seen 可以考虑放在事件回调之前,并提前把 cqe 结构体拷贝出来。这样可以提前给内核释放空间
  6. 可以考虑 使用 io_uring_queue_init_params 指定 wq_fd,让不同线程的 io_uring 实例复用同一个内核线程池,节省内核资源。

@xiaoyang-sde
Copy link
Owner Author

之前研究过一点io-uring

  • 有个小问题:multishot_accept 是怎么使用的没看懂。就我所知一个 multishot_sqe 会有多个 cqe,所有 cqe 的 data 都是一样的,这就和 coroutine 使用冲突,因为每次 resume 之后 coroutine address 都已经变了。
  • 还有一些小建议:
  1. 别用 splice。io-uring 目前版本的 splice 极其慢,比 read-send 慢很多
  2. 可以使用 IOLINK 减少 syscall 次数,比如 read(IOLINK)-send。这两个请求一次性 submit,send 会等待 read 执行成功后再执行。
  3. 建议使用同步版本的 cancel。异步的 cancel 不能保证IO请求被及时取消,导致 use-after-free 的情况
  4. 少用 std::function。std::function 会动态申请内存并有类型擦除机制,比直接调用函数慢很多。建议 io_uring::for_each_cqe 改成返回迭代器,这样既可以避免回调函数省去 std::function,而且普通循环更容易使用可以随时 break
  5. cqe_seen 可以考虑放在事件回调之前,并提前把 cqe 结构体拷贝出来。这样可以提前给内核释放空间
  6. 可以考虑 使用 io_uring_queue_init_params 指定 wq_fd,让不同线程的 io_uring 实例复用同一个内核线程池,节省内核资源。

感谢这些建议! multishot_accept 其实是写了个 bug... 按说每次 suspend 时要更新一下 sqe_data 的 coroutine_handle 地址, 这样下次 cqe 可以拿到正确的 coroutine handle

@xiaoyang-sde
Copy link
Owner Author

xiaoyang-sde commented Jun 9, 2023

Here are potential improvements:

  • Improve error handling with std::expected (C++ 23)
  • Refactor the templates with Concepts and universal references
  • Refactor iterations with std::ranges
  • Optimize the http_parser class
  • Mark functions in header files as inline
  • Remove unused constructors and operators
  • Provide basic exception guarantee
  • Implement when_all

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

2 participants