Hi, I just wanted to report back that my usage with libev iouring backend appears to be working super fine.
It is a WebSocket client opening about 64 TCP connections. The test has been performed with kernel 5.11.14. By switching from epoll backend to io_uring one, my process CPU usage did drop from 20-30% to below 5%. It seems too good to be true! What I suspect happening is that my socket option SO_BUSY_POLL setting might not be honored by io_uring. Ultimately, what I am looking to improve is my application reaction time. I might have more to say about io_uring effect on latency in 24h- 48h from now when I had the chance to collect some data. I believe that in order to achieve the performance gain that io_uring can deliver, you would need to service I/O through io_uring as well to save on the associated system call cost instead of just using io_uring for polling. ie: currently, if data is available for reading for my 64 sockets and I call read() 64 times from my libev io watcher callback. There is not much performance gain here by using io_uring. but if adding a function specific to libev io_uring backend that would let the watcher code perform their i/o requests through io_uring was thinkable, that could be the performance holy grail for libev users by only making 1 system call to service the 64 i/o operations. drawback of this optimization is that the watcher code couldn't be use anymore with the other backends but that is the cost to pay to be able to use a new API to its full potential... I will probably end-up modifying my local copy of libev to play with the idea. Let me know if there would be interest in knowing how my experiment goes. In the meantime, I took care of one of the TODO item. That is using a single mmap() when possible. It is essentially code from liburing adapted to libev coding style... $ diff ev_iouring.c.orig ev_iouring.c 64c64 < * occur to him, and he made good on it by adding an unlimited nuber --- > * occur to him, and he made good on it by adding an unlimited number 82c82 < /* TODO: take advantage of single mmap, NODROP etc. */ --- > /* TODO: take advantage of NODROP etc. */ 323c323,324 < if (iouring_cq_ring != MAP_FAILED) munmap (iouring_cq_ring, iouring_cq_ring_size); --- > if (iouring_cq_ring != MAP_FAILED && iouring_cq_ring != iouring_sq_ring) > munmap (iouring_cq_ring, iouring_cq_ring_size); 346c347 < if (!have_monotonic) /* cannot really happen, but what if11 */ --- > if (!have_monotonic) /* cannot really happen, but what if!! */ 360c361 < if ((~params.features) & (IORING_FEAT_NODROP | IORING_FEATURE_SINGLE_MMAP | IORING_FEAT_SUBMIT_STABLE)) --- > if ((~params.features) & (IORING_FEAT_NODROP | IORING_FEAT_SUBMIT_STABLE)) 380a382,388 > if (params.features & IORING_FEAT_SINGLE_MMAP) > { > if (iouring_cq_ring_size > iouring_sq_ring_size) > iouring_sq_ring_size = iouring_cq_ring_size; > iouring_cq_ring_size = iouring_sq_ring_size; > } > 383,384c391,395 < iouring_cq_ring = mmap (0, iouring_cq_ring_size, PROT_READ | PROT_WRITE, < MAP_SHARED | MAP_POPULATE, iouring_fd, IORING_OFF_CQ_RING); --- > if (params.features & IORING_FEAT_SINGLE_MMAP) > iouring_cq_ring = iouring_sq_ring; > else > iouring_cq_ring = mmap (0, iouring_cq_ring_size, PROT_READ | PROT_WRITE, > MAP_SHARED | MAP_POPULATE, iouring_fd, IORING_OFF_CQ_RING); 637c648 < /* we also clar the timeout if there are outstanding fdchanges */ --- > /* we also clear the timeout if there are outstanding fdchanges */ On Thu, 2020-03-19 at 09:34 +0100, Marc Lehmann wrote: > > Currently, the io_uring interface evelopment in libev is on hold, > > awaiting > > I might add, the iouring backend can be enabled in libev-4.33, and is > expected to work. It has not really received testing, and it doesn't > seem to > have speed benefits yet. > > Anybody is invited to experiment with it - just don't use it in > production. > _______________________________________________ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/mailman/listinfo/libev