es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Esperando simultáneamente epoll e io_uring

Estoy migrando mi proyecto a iouring para obtener un mejor rendimiento. Sin embargo, parte del sistema depende de epoll como sistema de eventos y no se puede mover a iouring (por ejemplo, los controladores de la base de datos escriben en el socket internamente y recibo notificaciones de eventos de lectura/escritura, sin ver nunca lo que se escribe en los sockets en bruto). Esto me obliga a usar epoll e iouring juntos. La creación de dos hilos, uno para epoll y otro para iouring, no es una opción por varias razones.

Mi plan era consultar io_uring después de epoll en mi bucle de eventos, de la siguiente manera:

“`c++
while(keep<em>running) {
epoll</em>wait();
io<em>uring</em>peek<em>batch</em>cqe();

<pre><code>… // manejar eventos
</code></pre>

}
“`

Esto resulta no ser viable. Es probable que no haya actividad de base de datos en curso, haciendo que epoll_wait bloquee hasta que se agote el tiempo de espera, por lo que todas las operaciones en iouring esperan el mismo tiempo de espera. Invertir el orden y llamar a io_uring_wait_cqe no es mejor. Es posible que haya tráfico en la base de datos pero que no se haya enviado nada a iouring, lo que hace que epoll espere el tiempo de espera de io_uring.

Hasta ahora he considerado reducir el tiempo de espera. Pero no es una solución elegante. Aumenta el uso de la CPU y agrega una latencia innecesaria. ¿Hay alguna manera de esperar a epoll e iouring al mismo tiempo? Es decir, alguna función que se desbloquee tan pronto como epoll o iouring tenga algo que procesar.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Desafortunadamente, no existe una manera sencilla de esperar tanto por epoll como por io_uring al mismo tiempo utilizando una única llamada de función. El problema al esperar por epoll e io_uring por separado, como ya ha descubierto, es que puede llevar a un bloqueo innecesario y aumentar la latencia.

    Una posible solución es utilizar la función epoll_wait con un tiempo de espera de 0, lo que le permitirá verificar si hay algún evento pendiente en el descriptor de archivo epoll sin bloquear. Si hay alguno, puede procesarlos inmediatamente antes de pasar a io_uring.

    Si no hay ningún evento en el descriptor de archivo epoll, entonces puede utilizar otra llamada al sistema, como io_uring_peek_batch_cqe, para verificar si hay alguna operación io_uring completada que pueda ser procesada.

    Alternando entre estas dos llamadas al sistema con un pequeño tiempo de espera entre ellas, puede esperar efectivamente tanto por epoll como por io_uring sin bloqueo ni latencia innecesarios. Sin embargo, este enfoque requiere una sintonización cuidadosa para encontrar los valores de tiempo de espera óptimos y asegurarse de que funcione de manera confiable con su aplicación y carga de trabajo específicas.

Comments are closed.