Primer aniversario del código abierto de Volo: optimización del rendimiento y construcción ecológica

Este artículo es el tercero de la serie de celebración del segundo aniversario de CloudWeGo.

Mirando hacia atrás en el trabajo realizado por el equipo CloudWeGo Rust el año pasado, si queremos resumirlo con dos palabras clave, es optimización del rendimiento y construcción ecológica . Este artículo se divide principalmente en tres puntos. El primer punto es resumir y revisar aproximadamente el desarrollo de Volo este año. El segundo punto es centrarse en la optimización del rendimiento en Volo. El tercer punto es que nuestro trabajo futuro se centrará en Cuál. aspectos.

1. Volo este año

En agosto de 2022, publicamos un anuncio oficial titulado " El primer marco RPC en China basado en el lenguaje Rust: Volo es oficialmente de código abierto Volo (completación de funciones y optimización del rendimiento), Pilota (actualización de capacidades), Motore (estabilización) y Metainfo (facilidad de uso).

En particular, nos gustaría llevarlo a revisar algunos de los nodos clave y las actualizaciones técnicas de Volo este año.

  • Poco después del código abierto, recibimos el primer PR del compañero de clase de la comunidad @anwentec. Este PR ayuda principalmente a los usuarios a usar Volo para el desarrollo en Windows, lo que complementa en gran medida el soporte multiplataforma del marco.

  • Inmediatamente después, marcamos el comienzo de la primera optimización importante del rendimiento desde el lanzamiento: reconstrucción de codificación y decodificación. Esta optimización se inspiró originalmente en un PR propuesto por el compañero de clase de la comunidad @ ii64 en Pilota para admitir el protocolo Thrift. En algunos casos, después de la discusión y la comunicación, Descubrimos que las capacidades existentes de Volo no pueden permitir que los usuarios ingresen códecs personalizados, por lo que tenemos la reconstrucción y optimización del códec Volo actual.

  • Vale la pena mencionar que durante este proceso, también lanzamos dos cajas, linkedbytes y faststr, que no solo ayudan en la optimización, sino que también enriquecen el ecosistema relacionado de código abierto de Rust.

  • Finalmente, en términos de codificación y decodificación, también omitimos algunas comprobaciones de límites mediante código inseguro, lo que permite que el compilador auxiliar genere instrucciones de operación paralela SIMD más eficientes, lo que mejora enormemente el rendimiento. Si desea conocer el progreso más detallado de Volo, puede consultar nuestra Nota de versión en el sitio web oficial de CloudWeGo .

2. Optimización del rendimiento

En el marco RPC, los aspectos que consumen más rendimiento son la serialización y la comunicación de red . Nuestra optimización del rendimiento se centra principalmente en estos dos puntos. La siguiente figura muestra un enlace de llamada RPC completo. Nuestro trabajo de optimización se concentra básicamente en estas tareas con uso intensivo de CPU y IO. La optimización de la reconstrucción de codificación y decodificación y la optimización de codificación y decodificación insegura que se presentarán en detalle a continuación se centran principalmente en. La parte de codificación y decodificación de serialización, si desea participar en una optimización profunda del rendimiento, esta será una buena referencia.

2.1 Optimización de la reconstrucción del códec

La optimización de esta área es principalmente la operación de copia cero de la memoria. Sabemos que al realizar una llamada RPC, la estructura de solicitud del usuario debe serializarse en un flujo de bytes binarios y almacenarse en la memoria en modo de usuario, y luego escribirse en la memoria en modo kernel a través de una llamada al sistema de escritura para enviar. -Copiar la parte que optimizamos es En el primer paso, se almacena en la memoria del modo de usuario. En la mayoría de las implementaciones, habrá una sobrecarga de copia para Stringestos Vec<u8>tipos de serialización, porque lo que se escribe en la llamada al sistema de escritura debe ser una memoria contigua. Entonces la pregunta es, si no se requiere escritura continua en memoria, ¿se puede omitir la copia aquí? La respuesta es obvia. Podemos ahorrar la sobrecarga de copia reutilizando la memoria en la estructura de solicitud del usuario y luego uniendo la memoria en forma de una lista vinculada para escribir.

Si desea reutilizar la memoria, es inevitable introducir un recuento de referencias para determinar cuándo se puede liberar esta memoria. Como resultado, los dos tipos originales de Stringy Vec<u8>no satisfacen las necesidades. Necesitamos tipos como Arc<String>y . Arc<Vec<u8>>Afortunadamente, Vec<u8>en la comunidad de código abierto ya existen Bytesestructuras en la biblioteca de bytes que pueden usarse como alternativas. Pero Stringno existe un buen reemplazo, y esta es una de las razones por las que nació la biblioteca faststr.

La biblioteca faststr proporciona principalmente una FastStrestructura. La representación en la estructura es la que se muestra a continuación. De hecho, es una colección de varios tipos de cadenas. Los usuarios pueden reducir mucha carga mental sobre cómo elegir tipos de cadenas. Además de cumplir con los requisitos anteriores para reutilizar la memoria, también tiene ciertas optimizaciones para cadenas pequeñas, como la asignación de memoria directamente en la pila. Por supuesto, algunas personas aquí tendrán preguntas. &strSi puede satisfacer las necesidades, ¿por qué todavía se necesita faststr? De hecho, no es el caso. En algunos escenarios, no podemos expresar su ciclo de vida. Para obtener una explicación detallada de esta parte, puede consultar la documentación de faststr.

StringLa biblioteca linkedbytes se basa principalmente en la idea de listas vinculadas y Vec<u8>escribe la memoria que reutilizamos anteriormente a través de la llamada al sistema writev. Hay dos partes principales en LinkedBytes, una es un campo que almacena temporalmente Stringmemoria que no es suma Vec<u8>y bytesla otra es un campo que une recuerdos list. Puede observar brevemente la lógica de la inserción. Al insertar Bytes, primero divida la memoria continua actualmente almacenada temporalmente e insértela list, y luego inserte la entrante Bytes.

2.2 Optimización de códecs inseguros

La optimización en esta área es principalmente para ayudar al compilador a ayudarnos a generar código ensamblador eficiente. Tomando la codificación como ejemplo, en circunstancias normales, cuando escribimos en la memoria Vec<i64>, será fácil escribir el código como se muestra a continuación, es decir, atravesar esto directamente Vecy luego llamar put_i64()al método para escribir.

Pero si observamos más de cerca put_i64()la implementación del método, encontraremos que cada vez que escribe, primero determinará si la memoria es suficiente. Si no es suficiente, expandirá la memoria antes de escribir. Entonces, si hemos asignado suficiente memoria desde el principio, podemos omitir por completo la verificación de límites aquí, por lo que podemos hacer una ligera modificación y escribir el código como se muestra a continuación.

Después de escribir el código, el siguiente paso es probar el rendimiento. Simplemente escriba un banco y ejecútelo. Si no lo ejecuta, no lo sabrá. Tal vez esté pensando lo mismo que pensábamos antes, simplemente eliminando la verificación de límites, la mejora del rendimiento no debería ser mucha, pero de hecho, mirando la figura a continuación, en realidad tiene de 7 a 8 veces el beneficio.

Entonces tenemos que analizar más de cerca ¿por qué? Como dice el refrán, si desea optimizar profundamente, el código ensamblador no se puede ejecutar. Convirtamos ambos a código ensamblador y mirémoslo nuevamente. Las siguientes dos imágenes capturan parte del código ensamblador durante el proceso de escritura.

Después de leer esto, creo que los estudiantes que están familiarizados con las instrucciones SIMD se han despertado repentinamente en el código ensamblador después de eliminar la verificación de límites, las instrucciones SIMD se utilizan para acelerar la escritura en la memoria, es decir, una instrucción puede escribir varios datos. Los beneficios de rendimiento también parecen razonables.

3. Perspectivas de futuro

Finalmente, les daré un spoiler sobre algunos de los proyectos que estamos probando actualmente y las partes en las que nos concentraremos en optimizar en el futuro.

1. Nuevos proyectos

El primero es el proyecto Shmipc-rs. Los estudiantes familiarizados con CloudWeGo pueden saber que Shmipc ahora es un proyecto de código abierto, pero es solo la implementación de las versiones del lenguaje Spec y Go es la implementación de la versión del lenguaje Rust. , que también se integrará en Volo para mejorar el rendimiento. Shmipc es una comunicación entre procesos basada en memoria compartida y es principalmente adecuada para paquetes grandes y escenarios de alto rendimiento.

El segundo es el proyecto Volo-http, que proporciona una experiencia de desarrollo consistente con el marco Axum ampliamente utilizado en la comunidad, y la parte de middleware se implementa en base a nuestro propio Motore de código abierto, lo que traerá algunas mejoras de rendimiento en el futuro. También se espera que se combine con el proyecto Volo-gRPC para proporcionar Gateway y otras funciones. Actualmente está disponible y todos son bienvenidos a experimentar y construir juntos.

2. Optimización de la facilidad de uso

La primera es la parte de documentación. Actualmente, hay muchas características funcionales en Volo, pero la mayoría de ellas carecen de documentación para explicar, por lo que los usuarios no pueden usarlas ni experimentarlas bien. En el futuro, incluiremos el trabajo de complementar la documentación. Haga un seguimiento del tema y todos son bienvenidos a participar.

La segunda es la parte de mejores prácticas. Actualmente, solo hay algunas demostraciones de ejemplo simples en Volo para que los usuarios las aprendan y las utilicen, pero no hay proyectos pequeños y medianos para que los usuarios aprendan y comprendan el marco de Volo. una parte que necesita ser fortalecida en el futuro. Si todos hay algún proyecto que recomienden implementar, pueden abrir un tema y discutirlo juntos.

Lo anterior es una revisión y una perspectiva del primer aniversario del código abierto de Volo con motivo del segundo aniversario de CloudWeGo. Espero que sea de ayuda para todos.

dirección del proyecto

GitHub: https://github.com/cloudwego Sitio web oficial: www.cloudwego.io

Los recursos pirateados de "Celebrating More Than Years 2" se cargaron en npm, lo que provocó que npmmirror tuviera que suspender el servicio unpkg. El equipo de inteligencia artificial de Microsoft en China empacó colectivamente y se fue a los Estados Unidos, involucrando a cientos de personas. Biblioteca de visualización frontal y el conocido proyecto de código abierto ECharts de Baidu: "ir al mar" para respaldar a Fish. ¡ Los estafadores utilizaron TeamViewer para transferir 3,98 millones! ¿Qué deberían hacer los proveedores de escritorio remoto? Zhou Hongyi: No queda mucho tiempo para que Google recomiende que todos los productos sean de código abierto. Un ex empleado de una conocida empresa de código abierto dio la noticia: después de ser desafiado por sus subordinados, el líder técnico se enfureció. Despidió a la empleada embarazada. Google mostró cómo ejecutar ChromeOS en una máquina virtual de Android. Por favor, dame un consejo, ¿qué papel juega aquí time.sleep(6)? Microsoft responde a los rumores de que el equipo de IA de China está "haciendo las maletas para Estados Unidos" El People's Daily Online comenta sobre la carga tipo matrioska del software de oficina: Sólo resolviendo activamente los "conjuntos" podremos tener un futuro
{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/4843764/blog/11043974
Recomendado
Clasificación