linux - Rendimiento del IPC: tubería con zócalo con nombre
performance sockets (9)
Como a menudo, los números dicen más que sentimiento, aquí hay algunos datos: Pipe vs Unix Socket Performance (opendmx.net) .
Este punto de referencia muestra una diferencia de aproximadamente 12 a 15% de velocidad más rápida para las tuberías.
Todo el mundo parece decir que los tubos con nombre son más rápidos que los enchufes IPC. ¿Cuánto más rápido son? Preferiría usar sockets porque pueden hacer comunicación bidireccional y son muy flexibles, pero elegirán velocidad sobre flexibilidad si es en cantidad considerable.
Las tuberías y tomas con nombre no son funcionalmente equivalentes; los zócalos proporcionan más características (son bidireccionales, para empezar).
No podemos decirte qué funcionará mejor, pero sospecho que no importa.
Los sockets de dominio Unix harán más o menos lo que harán los zócalos tcp, pero solo en la máquina local y con (quizás un poco) menor sobrecarga.
Si un socket Unix no es lo suficientemente rápido y está transfiriendo una gran cantidad de datos, considere usar memoria compartida entre su cliente y su servidor (lo cual es MUCHO más complicado de configurar).
Tanto Unix como NT tienen "Cadenas con nombre" pero son totalmente diferentes en el conjunto de características.
Para comunicación bidireccional con canalizaciones con nombre:
- Si tiene pocos procesos, puede abrir dos tubos para dos direcciones (processA2ProcessB y processB2ProcessA)
- Si tiene muchos procesos, puede abrir tuberías de entrada y salida para cada proceso (processAin, processAout, processBin, processBout, processCin, processCout, etc.)
- O puedes ir híbrido como siempre :)
Las tuberías con nombre son bastante fáciles de implementar.
Por ejemplo, implementé un proyecto en C con canalizaciones con nombre, gracias a la comunicación basada en entrada y salida del archivo estándar (fopen, fprintf, fscanf ...) fue muy fácil y limpio (si eso también es una consideración).
Incluso los codifiqué con java (estaba serializando y enviando objetos sobre ellos).
Las tuberías con nombre tienen una desventaja:
- no escalan en múltiples computadoras como sockets, ya que dependen del sistema de archivos (suponiendo que el sistema de archivos compartido no es una opción)
Puede usar una solución liviana como ZeroMQ [ zmq / 0mq ]. Es muy fácil de usar y dramáticamente más rápido que los enchufes.
Si no necesitas velocidad, ¡los enchufes son la forma más fácil de hacerlo!
Si lo que está mirando es la velocidad, la solución más rápida es la memoria compartida, las tuberías sin nombre.
Sugeriría que tomes el camino fácil primero, aislando cuidadosamente el mecanismo ipc para que puedas cambiar de socket a pipe, pero definitivamente iré primero con socket. Debe asegurarse de que el rendimiento del IPC sea un problema antes de realizar una optimización preventiva.
Y si tiene problemas debido a la velocidad del IPC, creo que debería considerar cambiar a la memoria compartida en lugar de ir a la red.
Si desea hacer algunas pruebas de velocidad de transferencia, debe probar socat , que es un programa muy versátil que le permite crear casi cualquier tipo de túnel.
Tenga en cuenta que los sockets no necesariamente significan IP (y TCP o UDP). También puede usar conectores UNIX (PF_UNIX), que ofrecen una notable mejora en el rendimiento al conectarse a 127.0.0.1
Un problema con los sockets es que no tienen una forma de descargar el búfer. Hay algo llamado algoritmo Nagle que recopila todos los datos y los vacía después de 40 ms. Entonces, si se trata de capacidad de respuesta y no de ancho de banda, es posible que sea mejor con una tubería.
Puede desactivar Nagle con la opción de socket TCP_NODELAY, pero luego el final de lectura nunca recibirá dos mensajes cortos en una sola llamada de lectura.
Así que pruébelo, terminé con nada de esto e implementé colas basadas en mapas de memoria con pthread mutex y semáforo en la memoria compartida, evitando muchas llamadas al sistema kernel (pero hoy ya no son muy lentas).
Voy a estar de acuerdo con shodanex, parece que estás tratando prematuramente de optimizar algo que todavía no es problemático. A menos que sepas que los enchufes van a ser un cuello de botella, simplemente los usaré.
Una gran cantidad de personas que juran por tuberías nombradas encuentran un pequeño ahorro (dependiendo de qué tan bien esté escrito todo lo demás), pero terminan con un código que pasa más tiempo bloqueando una respuesta IPC que haciendo un trabajo útil. Claro, los esquemas sin bloqueo ayudan a esto, pero pueden ser complicados. Pasando años aportando código antiguo a la era moderna, puedo decir que la aceleración es casi nula en la mayoría de los casos que he visto.
Si realmente crees que los sockets van a ralentizarte, sal de la puerta usando la memoria compartida prestando especial atención a cómo usas los bloqueos. Nuevamente, en realidad, es posible que encuentre una aceleración pequeña, pero observe que está desperdiciando una porción de ella esperando en cerraduras de exclusión mutua. No voy a abogar por un viaje al infierno futex (bueno, ya no es el infierno en 2015, dependiendo de tu experiencia).
Libra por libra, los sockets son (casi) siempre la mejor manera de ir para el espacio de usuario IPC bajo un kernel monolítico ... y (generalmente) el más fácil de depurar y mantener.