Andrew Phillips ha trabajado en el corredor LMAX durante 17 años y actualmente es el director de tecnología (CTO) de la empresa. Su presupuesto se mide en milisegundos.
Aunque la latencia de extremo a extremo que LMAX garantiza para operaciones de alta frecuencia es de 50 ms, el tiempo máximo que se permite ejecutar cualquier aplicación es de ocho nanosegundos. Cuando el presupuesto se mide en nanosegundos, incluso el retraso potencial más pequeño tiene un impacto negativo.
“Nuestros clientes son las grandes casas comerciales y quieren algo que funcione muy rápido y de manera muy determinista”, dice Phillips.
“Probaremos varios cables Twinax y usaremos conexión directa en lugar de fibra óptica, porque se necesita una cantidad pequeña pero mensurable de nanosegundos para convertir una señal eléctrica en luz, transmitirla a través de una fibra y luego volver a convertirla en una señal eléctrica”.
Un enfoque diferente al rendimiento del software
Cuando la empresa comenzó a construir su plataforma en 2010, Phillips dice que era una práctica común utilizar una metodología en cascada y desarrollar el software utilizando el lenguaje de programación C++. Sin embargo, el intercambio de LMAX se construye utilizando una metodología ágil y está programado en Java.
“Utilizar técnicas ágiles y Java, con su ecosistema de pruebas inmensamente rico, se consideraba bastante extraño”, afirma.
A diferencia de C++, donde el código de la aplicación se compila primero en un programa de código de máquina que luego se ejecuta directamente en un microprocesador (procesador), Java es un lenguaje de programación que utiliza compilación en tiempo de ejecución. Esto significa que el código Java se compila “sobre la marcha” mientras se ejecuta el programa.
Java también ofrece gestión de memoria integrada llamada “recolección de basura”, que puede afectar el rendimiento de un programa, como explica Phillips: “Tenemos muchas preguntas incómodas de clientes potenciales sobre picos de latencia y recolección de basura.
“Comenzamos con el JDK estándar en 2013. Nos dimos cuenta de que Java tenía una herencia: estaba diseñado para decodificadores y era más feliz cuando le dabas unos 4 GB de memoria”.
Según Phillips, más de 4 GB de memoria del sistema significaba que los tiempos de recolección de basura se volvían inestables desde una perspectiva de latencia. “No queríamos sacrificar la expresividad o la velocidad de escritura en Java, ni tampoco el ecosistema de pruebas, que realmente ha sustentado gran parte de nuestro éxito”.
La empresa ha estado utilizando la plataforma Java del sistema Azul para sortear las limitaciones de memoria del entorno Java estándar. “En ese momento, si tenía un servidor con 64 Gb de memoria, era esencial evitar la recolección de basura”, añade Phillips.
Azul, afirma, sólo recoge basura como último recurso. “Esto es fantástico para nosotros porque estábamos reduciendo nuestra latencia de intercambio, en ese momento, desde un milisegundo hasta donde estamos ahora, que es 50 microsegundos”.
Y dentro de esa pequeña ventana de 50 microsegundos, suceden muchísimas cosas. “50 microsegundos es el tiempo que lleva desde que se envía un pedido en el borde de nuestra red hasta que se procesa, se compara y luego se envía el acuse de recibo”, añade Phillips.
“A menos que sea un desarrollador de compiladores profesional, desafío incluso a los programadores más buenos a hacerlo tan bien como un compilador en términos de optimización”
Andrew Phillips
Con esta ventana de 50 microsegundos, el código Java tiene sólo ocho nanosegundos para ejecutarse, ya que la mayor parte de la latencia se produce cuando la transacción pasa a través de la infraestructura de red hasta el servidor. Phillips cree que Java, como lenguaje de programación, es mejor para optimizar el código en comparación con alguien que codifica manualmente para lograr un alto rendimiento.
“Tengo experiencia en C, C++ y Fortran, y uno tiende a recurrir al lenguaje ensamblador para hacer que las cosas funcionen más rápido. [Java] Es un poco contradictorio”, dice.
Según Phillips, los microprocesadores modernos son tan fantásticamente complicados que si un desarrollador elige escribir algo en C o C++, el código se optimiza sólo para la arquitectura del procesador “objetivo” que el desarrollador configuró en la herramienta de compilación de C o C++.
“Una de las ventajas de ejecutar Java es que está optimizado para el procesador en el que se está ejecutando”, afirma. “Eso puede ser bastante importante. A falta de ser un desarrollador de compiladores profesional, desafío incluso a los programadores más buenos a que lo hagan tan bien como un compilador en términos de optimización”.
Normalmente, un programador de C++ usaría el compilador de C++ en su máquina de desarrollo para compilar la aplicación, usando el procesador del servidor como arquitectura de destino. Esto se soluciona efectivamente y la aplicación solo se optimiza para ese procesador de servidor en particular.
Pero, como señala Phillips, los entornos de desarrollo y prueba pueden tener varias generaciones de arquitectura de procesador detrás de los servidores de producción. También es probable que los entornos de prueba, donde el código se mueve antes de entrar en producción, ejecuten generaciones más antiguas de procesadores de servidor.
Java puede optimizar el código en tiempo de ejecución y, por lo tanto, aprovechar cualquier función de aceleración de código disponible en el hardware de destino en el que se ejecuta el código.
“Como soy un poco incrédulo, estaba bastante escéptico de que Java pudiera hacer esto”, dice Phillips. “Me convertí después de tener una competencia de codificación entre un programador experto en Java y yo, escribiendo en C y lenguaje ensamblador. Simplemente no podía superar la velocidad del programa Java”.
Cuando se le pregunta cuál es el mayor desafío que enfrenta, Phillps dice: “Lo que más me frena en Java es poder acceder a una gran cantidad de memoria con latencias deterministas muy bajas. Este es uno de nuestros principales desafíos de ingeniería. El mayor problema que tengo ahora probablemente sea la latencia de la memoria”.
Avances en tecnología de baja latencia
De cara al futuro, Phillips dice que está impresionado por las oportunidades en latencia de hardware que promete la tecnología CXL. Compute Express Link (CXL) permite la conectividad de memoria directa entre diferentes bits de hardware.
“CXL tiene un enorme potencial para cambiar completamente lo que hacemos porque la diferencia entre el bus de memoria, el bus periférico y la capa de red comienza a difuminarse en uno”, dice.
Sin embargo, si bien CXL fue promocionado como una tecnología que cambiaría la arquitectura del hardware informático en cuestión de meses, aún tiene que ganar terreno. Haciendo una analogía entre CXL y la energía de fusión, Phillips añade: “Siempre son 10 años. La idea de realizar llamadas a procedimientos remotos a través de un tejido CXL es muy atractiva”.
Para Phillips, CXL ofrece una manera de evitar la sobrecarga de los protocolos de red tradicionales. “Todo se ejecuta en UDP IP o TCP IP, que son [networking] protocolos diseñados allá por los años 1960 y principios de los 70, cuando un módem de acceso telefónico [connectivity] era lo último en tecnología”.
Si bien reconoce el “fantástico esfuerzo de ingeniería” que ha permitido que estos protocolos evolucionen hasta donde están ahora con Ethernet de 25 gigabits, Phillips afirma: “Sería agradable y haría las cosas mucho más rápidas si no tuviéramos los gastos generales de Encapsulación de IP”.
Este trabajo continuo de exploración del arte de lo posible ayuda a LMAX a procesar transacciones comerciales con la menor latencia que permiten las leyes de la física, le brinda a la empresa un amortiguador y le permite manejar un rendimiento inesperadamente alto.
Por ejemplo, recordando la enorme volatilidad en el mercado de las criptomonedas que ocurrió el año pasado y que hizo que los intercambios de criptomonedas cayeran, Phillips dice: “No bajamos. De hecho, vimos un aumento masivo en el volumen a medida que las personas se estaban transfiriendo riesgos en nuestro intercambio entre sí”.
Aunque el volumen de operaciones no se acercó al máximo que LMAX podía manejar, dice que la compañía pudo manejar las operaciones para todo el mercado criptográfico y, según Phillips, había mucho margen de maniobra.