Rendimiento de IPC: tubería con nombre frente a enchufe


114

Todo el mundo parece decir que las canalizaciones con nombre son más rápidas que los sockets IPC. ¿Cuánto más rápido son? Preferiría usar sockets porque pueden hacer comunicación bidireccional y son muy flexibles, pero elegiré la velocidad sobre la flexibilidad si es en una cantidad considerable.


10
Su kilometraje variará. :) Analice el uso típico para su aplicación prevista y elija el mejor de los dos. Luego, perfile conductos anónimos, sockets de otros dominios y familias, semáforos y memoria compartida o colas de mensajes (SysV y POSIX), señales en tiempo real con una palabra de datos, o lo que sea. pipe(2)(er,? mkfifo(3)) puede ser el ganador, pero no lo sabrá hasta que lo intente.
Pilcrow

2
Colas de mensajes SysV FTW! No tengo idea de si son rápidos, solo tengo debilidad por ellos.
Tom Anderson

4
¿Qué es "velocidad" en este caso? ¿Tasa general de transferencia de datos? ¿O latencia (qué tan rápido llega el primer byte al receptor)? Si desea una transferencia de datos local rápida, es difícil superar la memoria compartida. Sin embargo, si la latencia es un problema, entonces la pregunta se vuelve más interesante ...
Ian Ni-Lewis

Respuestas:


64

Le sugiero que tome el camino fácil primero, aislando cuidadosamente el mecanismo de IPC para que pueda cambiar de enchufe a tubería, pero definitivamente iría con el enchufe primero. Debe asegurarse de que el rendimiento de IPC sea un problema antes de optimizar de forma preventiva.

Y si se mete en problemas debido a la velocidad del IPC, creo que debería considerar cambiar a memoria compartida en lugar de utilizar una canalización.

Si desea realizar algunas pruebas de velocidad de transferencia, debería probar socat , que es un programa muy versátil que le permite crear casi cualquier tipo de túnel.


48

Los mejores resultados que obtendrá con la solución de memoria compartida .

Las tuberías con nombre son solo un 16% mejores que los sockets TCP .

Los resultados se obtienen con la evaluación comparativa de IPC :

  • Sistema: Linux (Linux ubuntu 4.4.0 x86_64 i7-6700K 4.00GHz)
  • Mensaje: 128 bytes
  • Número de mensajes: 1000000

Punto de referencia de tubería:

Message size:       128
Message count:      1000000
Total duration:     27367.454 ms
Average duration:   27.319 us
Minimum duration:   5.888 us
Maximum duration:   15763.712 us
Standard deviation: 26.664 us
Message rate:       36539 msg/s

Punto de referencia FIFOs (canalizaciones con nombre):

Message size:       128
Message count:      1000000
Total duration:     38100.093 ms
Average duration:   38.025 us
Minimum duration:   6.656 us
Maximum duration:   27415.040 us
Standard deviation: 91.614 us
Message rate:       26246 msg/s

Punto de referencia de la cola de mensajes:

Message size:       128
Message count:      1000000
Total duration:     14723.159 ms
Average duration:   14.675 us
Minimum duration:   3.840 us
Maximum duration:   17437.184 us
Standard deviation: 53.615 us
Message rate:       67920 msg/s

Punto de referencia de memoria compartida:

Message size:       128
Message count:      1000000
Total duration:     261.650 ms
Average duration:   0.238 us
Minimum duration:   0.000 us
Maximum duration:   10092.032 us
Standard deviation: 22.095 us
Message rate:       3821893 msg/s

Punto de referencia de sockets TCP:

Message size:       128
Message count:      1000000
Total duration:     44477.257 ms
Average duration:   44.391 us
Minimum duration:   11.520 us
Maximum duration:   15863.296 us
Standard deviation: 44.905 us
Message rate:       22483 msg/s

Prueba comparativa de sockets de dominio Unix:

Message size:       128
Message count:      1000000
Total duration:     24579.846 ms
Average duration:   24.531 us
Minimum duration:   2.560 us
Maximum duration:   15932.928 us
Standard deviation: 37.854 us
Message rate:       40683 msg/s

Punto de referencia ZeroMQ:

Message size:       128
Message count:      1000000
Total duration:     64872.327 ms
Average duration:   64.808 us
Minimum duration:   23.552 us
Maximum duration:   16443.392 us
Standard deviation: 133.483 us
Message rate:       15414 msg/s

1
Gracias por la evaluación comparativa detallada. ¿Quiere decir "multiprocesamiento. Cola" con "Cola de mensajes"?
ovunccetina

1
Message Queue es una cola de mensajes XSI del sistema ( man7.org/linux/man-pages/man0/sys_msg.h.0p.html )
chronoxor

34

Estoy de acuerdo con shodanex, parece que intentas optimizar prematuramente algo que aún no es problemático. A menos que sepa que los sockets van a ser un cuello de botella, simplemente los usaría.

Muchas personas que confían en las tuberías con nombre 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 de IPC que haciendo un trabajo útil. Claro, los esquemas sin bloqueo ayudan en esto, pero pueden ser complicados. Pasando años trayendo 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 cree que los sockets lo ralentizarán, salga por la puerta usando la memoria compartida y preste especial atención a cómo usa las cerraduras. Una vez más, en realidad, es posible que encuentre una pequeña aceleración, pero observe que está desperdiciando una parte esperando bloqueos de exclusión mutua. No voy a defender un viaje al infierno futex (bueno, no todo el infierno más en 2015, dependiendo de su experiencia).

Libra por libra, los sockets son (casi) siempre la mejor manera de obtener el espacio de usuario IPC bajo un kernel monolítico ... y (generalmente) los más fáciles de depurar y mantener.


2
tal vez algún día en un futuro utópico distante tendremos un núcleo moderno, modular y completamente nuevo que implícitamente ofrece todas las habilidades (entre procesos y otras) que actualmente caminamos sobre vidrios rotos para lograr ... pero bueno ... uno puede soñar
Gukki5 21/08/18

27

Tenga en cuenta que sockets no significa necesariamente IP (y TCP o UDP). También puede utilizar sockets UNIX (PF_UNIX), que ofrecen una mejora notable del rendimiento en comparación con la conexión a 127.0.0.1


1
¿Qué pasa con Windows?
Pacerier

1
@Pacerier Lamentablemente, no puede crear sockets locales en Windows de la misma manera que el espacio de nombres abstracto en UNIX. He descubierto que los sockets PF_UNIX son sustancialmente más rápidos (> 10%) que la mayoría de los otros métodos descritos en esta página.
EntangledLoops

1
devblogs.microsoft.com/commandline/af_unix-comes-to-windows actualización, los sockets Unix están disponibles en Windows 10 ahora.
eri0o


11

Si no necesita velocidad, ¡los enchufes son la forma más fácil de hacerlo!

Si lo que busca es velocidad, la solución más rápida es la memoria compartida, no las canalizaciones con nombre.


8

Para comunicación bidireccional con canalizaciones con nombre:

  • Si tiene pocos procesos, puede abrir dos conductos en 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-salida de archivos estándar (fopen, fprintf, fscanf ...) fue tan 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 se escalan en varias computadoras como sockets, ya que dependen del sistema de archivos (asumiendo que el sistema de archivos compartido no es una opción)

8

Un problema con los sockets es que no tienen forma de vaciar el búfer. Existe algo llamado algoritmo de 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, puede que sea mejor con una tubería.

Puede desactivar Nagle con la opción de socket TCP_NODELAY, pero el final de la lectura nunca recibirá dos mensajes cortos en una sola llamada de lectura.

Así que pruébelo, terminé sin 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 del kernel (pero hoy ya no son muy lentas).


3
"Así que pruébalo" <- palabras para vivir.
Koshinae

6

Las tuberías y enchufes con nombre no son funcionalmente equivalentes; Los sockets proporcionan más funciones (son bidireccionales, para empezar).

No podemos decirle cuál funcionará mejor, pero sospecho que no importa.

Los sockets de dominio Unix harán más o menos lo que los sockets tcp, pero solo en la máquina local y con (quizás un poco) menos gastos generales.

Si un socket Unix no es lo suficientemente rápido y está transfiriendo muchos datos, considere usar memoria compartida entre su cliente y servidor (que es MUCHO más complicado de configurar).

Unix y NT tienen "canalizaciones con nombre" pero son totalmente diferentes en el conjunto de características.


1
Bueno, si abres 2 tubos, también obtienes comportamiento bidi.
Pacerier

4

Puede utilizar una solución ligera como ZeroMQ [ zmq / 0mq ]. Es muy fácil de usar y mucho más rápido que los enchufes.


2
Puede que te guste, adivina Amit, la próxima obra de arte de Martin SUSTRIK: compatible con POSIX nanomsg. De todos modos, da la bienvenida y disfruta de este gran lugar y conviértete en miembro contribuyente activo.
user3666197
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.