2009-08-05 18 views
70

Todo el mundo parece decir que las tuberías con nombre son más rápidas que las tomas 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.Rendimiento de IPC: Canalizado vs Socket

+10

Su millaje variará. :) Perfile el uso típico para su aplicación deseada, y elija el mejor de los dos. A continuación, perfile tuberías anónimas, tomas 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 pruebe. – pilcrow

+2

Cola de mensajes SysV FTW! No tengo idea de si son rápidos, solo tengo un punto débil para ellos. –

+2

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

Respuesta

4

Las tuberías y tomas designadas no son funcionalmente equivalentes; los zócalos proporcionan más características (son bidireccionales, para empezar).

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

Los sockets de dominio Unix harán prácticamente lo mismo que los sockets tcp, pero solo en la máquina local y con (tal vez un poco) sobrecarga.

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

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

+1

Bueno, si abre 2 tubos, también obtendrá un comportamiento bidi. – Pacerier

46

Le sugiero que tome el camino fácil primero, aislando cuidadosamente el mecanismo ipc para que pueda cambiar de un socket a otro, pero definitivamente iría primero con el socket. Debe asegurarse de que el rendimiento de IPC sea un problema antes de realizar una optimización preventiva.

Y si se mete en problemas debido a la velocidad del IPC, creo que debería considerar cambiar a la memoria compartida en lugar de ir a la tubería.

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.

+2

+1 para socat, no había visto eso antes de – galaktor

+1

@shodanex, ¿Por "memoria compartida" quiere decir hilos o ...? – Pacerier

25

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 sepa las tomas van a ser un cuello de botella, solo las usaría.

Mucha gente que confía en los tubos con nombre encuentra un pequeño ahorro (dependiendo de qué tan bien esté escrito todo), pero termina 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 cree que los sockets van a reducir la velocidad, salga por la puerta utilizando la memoria compartida prestando especial atención a cómo usa 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 futex hell (bueno, no bastante infierno en 2015, dependiendo de su experiencia).

Libra por libra, los sockets son (casi) siempre la mejor manera de ir para el espacio de usuario IPC bajo un núcleo monolítico ... y (generalmente) el más fácil de depurar y mantener.

6

¡Si no necesita 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, no las tuberías con nombre.

7

Para la comunicación de dos vías con canalizaciones con nombre:

  • Si tiene pocos procesos, puede abrir dos tubos de dos direcciones (processA2ProcessB y processB2ProcessA)
  • Si usted tiene muchos procesos, puede abrir en y fuera tubos para cada proceso (processAin, processAout, processBin, processBout, processCin, processCout etc)
  • o puede ir híbrido como siempre :)

Nam Los tubos de audio son bastante fáciles de implementar.

E.g. Implementé un proyecto en C con canalizaciones con nombre, gracias a la comunicación basada en entrada-salida del archivo estándar (fopen, fprintf, fscanf ...) fue muy fácil y limpio (si eso también es una consideración).

Incluso les estará con java (me la serialización y el envío de objetos sobre ellos!)

Las canalizaciones con nombre tiene una desventaja:

  • que no escalan en varios equipos como enchufes ya que dependen de sistema de archivos (suponiendo sistema de archivos compartido no es una opción)
20

Tenga en cuenta que las tomas no significa necesariamente IP (y TCP o UDP). También puede usar sockets UNIX (PF_UNIX), que ofrecen una notable mejora en el rendimiento al conectarse a 127.0.0.1

+1

¿Qué pasa con Windows? – Pacerier

+1

@Pacerier Lamentablemente, no puede crear sockets locales en Windows del mismo modo que el espacio de nombres abstracto en UNIX. He encontrado 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

4

Un problema con los zócalos es que no tienen forma de eliminar 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 deshabilitar 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 memoria compartida, evitando muchas llamadas al sistema del kernel (pero hoy ya no son muy lentas).

+1

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

1

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.

+1

Quizás te guste, adivina Amit, la siguiente obra de arte de Martin SUSTRIK: POSIX cumple ** 'nanomsg' **. De todos modos, bienvenido y disfrute de este gran lugar y conviértase en miembro contribuyente. – user3666197

+0

Lo intentaré seguro, gracias. –