Support handling TCP I/O in simple separate io_uring-based I/O threads

Required mainly for clients, allows to scale parallel client I/O with TCP
from 100-150k iops to ~400k iops and from 2-3 GB/s to at least 7-8 GB/s
with 4 I/O threads, at the same time increasing Q=1 latency by 2x thread
switching delay, which is ~10 us when CPU powersaving is disabled and may
be as high as 200 us when it's enabled.
This commit is contained in:
Vitaliy Filippov
2024-07-04 13:29:20 +03:00
parent 21d1171ba4
commit abbba6ade4
14 changed files with 331 additions and 19 deletions
+5 -11
View File
@@ -14,6 +14,7 @@
#include <string>
#include <functional>
#include <vector>
#include <mutex>
#define RINGLOOP_DEFAULT_SIZE 1024
@@ -124,28 +125,21 @@ class ring_loop_t
std::vector<std::function<void()>> immediate_queue, immediate_queue2;
std::vector<ring_consumer_t*> consumers;
struct ring_data_t *ring_datas;
std::mutex mu;
bool mt;
int *free_ring_data;
unsigned free_ring_data_ptr;
bool loop_again;
struct io_uring ring;
int ring_eventfd = -1;
public:
ring_loop_t(int qd);
ring_loop_t(int qd, bool multithreaded = false);
~ring_loop_t();
void register_consumer(ring_consumer_t *consumer);
void unregister_consumer(ring_consumer_t *consumer);
int register_eventfd();
inline struct io_uring_sqe* get_sqe()
{
if (free_ring_data_ptr == 0)
return NULL;
struct io_uring_sqe* sqe = io_uring_get_sqe(&ring);
assert(sqe);
*sqe = { 0 };
io_uring_sqe_set_data(sqe, ring_datas + free_ring_data[--free_ring_data_ptr]);
return sqe;
}
io_uring_sqe* get_sqe();
inline void set_immediate(const std::function<void()> cb)
{
immediate_queue.push_back(cb);