Estoy haciendo algunos benchmarks con un selector optimizado Java NIO en Linux sobre loopback (127.0.0.1).Secuencia mínima posible del selector Java NIO
Mi prueba es muy simple:
- Un programa envía un paquete UDP a otro programa que se hace eco de vuelta al remitente y se calcula el tiempo de ida y vuelta. El siguiente paquete solo se envía cuando se anota el anterior (cuando vuelve). Se realiza un calentamiento adecuado con un par de millones de mensajes antes de que se realice el punto de referencia. El mensaje tiene 13 bytes (sin contar los encabezados UDP).
Para el tiempo de ida y vuelta consigo los siguientes resultados:
- min Tiempo: 13 micros
- Prometio: 19 micros
- 75% percentil: 18,567 nanos
- 90% percentil: 18,789 nanos
- 99% percentil: 19,184 nanos
- 99.9% percentil: 19,264 nanos
- 99,99% percentil: 19.310 nanos
- 99,999% percentil: 19.322 nanos
pero el problema aquí es que Estoy hilando 1 millón de mensajes.
si hilo sólo 10 mensajes que consiguen resultados muy diferentes:
- min Tiempo: 41 micros
- Tiempo medio: 160 micros
- 75% percentil: 150,701 Nanos
- 90% percentil : 155,274 nanos
- 99% percentil: 159,995 nanos
- 99,9% percentil: 159,995 nanos
- 99,99% percentil: 159.995 nanos
- 99,999% percentil: 159.995 nanos
Corrígeme si estoy equivocado, pero sospecho que una vez que tengamos el selector NIO girar los tiempos de respuesta se hacen óptima. Sin embargo, si estamos enviando mensajes con un intervalo lo suficientemente grande entre ellos, pagamos el precio de activar el selector.
Si juego con el envío de un solo mensaje consigo varias veces entre 150 y 250 micros.
Así que mis preguntas para la comunidad son:
1 - ¿Es mi tiempo mínimo de 13 micros con promedio de 19 micros óptimas para esta prueba de paquetes de ida y vuelta. Parece que estoy ganando ZeroMQ por lejos, así que me puede faltar algo aquí.A partir de este punto de referencia, parece que ZeroMQ tiene un tiempo promedio de 49 micros (99% percentil) en un núcleo estándar =>http://www.zeromq.org/results:rt-tests-v031
2 - ¿Hay algo que pueda hacer para mejorar el tiempo de reacción del selector cuando giro un solo o muy algunos mensajes? 150 micros no se ve bien. ¿O debería suponer que en un entorno prod el selector no será del todo?
Al hacer el giro activo alrededor de selectNow() Puedo obtener mejores resultados. Enviar pocos paquetes es aún peor que enviar muchos paquetes, pero creo que ahora estoy alcanzando el límite de rendimiento del selector. Mis resultados:
- Envío de un paquete único Obtengo un tiempo de ida y vuelta de 65 micros consistente.
- Enviando dos paquetes Obtengo alrededor de 39 micros el tiempo de ida y vuelta en promedio.
- Enviando 10 paquetes Obtengo alrededor de 17 micros de ida y vuelta en promedio.
- Envío de 10.000 paquetes Obtengo alrededor de 10.098 nanos en tiempo de ida y vuelta en promedio.
- Enviando 1 millón de paquetes Obtengo 9,977 nanos en tiempo de ida y vuelta en promedio.
Conclusiones
Así que parece que la barrera física para la ida y vuelta de paquetes UDP es un promedio de 10 microsegundos, aunque tengo algunos paquetes que hacen el viaje en 8 micros (tiempo min) .
Con el giro ocupado (gracias Peter) pude pasar de 200 micros en promedio a un promedio de 65 micros en un solo paquete.
No estoy seguro de por qué ZeroMQ es 5 times slower que eso. (Editar: Tal vez porque estoy probando esta en la misma máquina a través de bucle de retorno y ZeroMQ está utilizando dos máquinas diferentes?)
Creo que gran parte de esto se debe a los tiempos de calentamiento de HotSpot JVM en lugar del comportamiento de los selectores específicamente. – EJP
Gracias @EJP, pero hice un poco de calentamiento con la JVM en modo de servidor. Envié un par de millones de mensajes antes de enviar los mensajes que activarán el punto de referencia. ¿Por qué crees que eso está pasando? = "Si juego con el envío de un solo mensaje, recibo varias veces entre 150 y 250 micros". – Julie
llámame loco, pero ¿por qué no acabas de volver a implementar tu programa corto (en la descripción) en C y ver el rendimiento? – NoSenseEtAl