Ejecución dinámica

Informar un problema Ver fuente . Por la noche · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

La ejecución dinámica es una función en Bazel con la que la ejecución local y remota de la misma acción se inician en paralelo, con el resultado de la primera rama que finalice, cancelando la otra rama. Combina la potencia de ejecución o una gran caché compartida de un sistema de compilación remoto con la baja latencia de para la ejecución, lo que ofrece lo mejor de ambos mundos para compilaciones limpias e incrementales. por igual.

En esta página, se describe cómo habilitar, ajustar y depurar la ejecución dinámica. Si tienen configurada la ejecución local y remota e intentan ajustar Bazel para lograr un mejor rendimiento, esta página es para ti. Si aún no tienes configuración de la ejecución remota, ve a Remote Execution de Bazel Overview.

¿Quieres habilitar la ejecución dinámica?

El módulo de ejecución dinámica es parte de Bazel, pero para usar ya debes poder compilar de forma local y remota con la misma configuración de Bazel.

Para habilitar el módulo de ejecución dinámica, pasa --internal_spawn_scheduler. a Bazel. Esto agrega una nueva estrategia de ejecución llamada dynamic. Ahora puedes use esto como su estrategia para los mnemónicos que desea ejecutar dinámicamente, como --strategy=Javac=dynamic Consulta la siguiente sección para saber cómo elegir los mnemónicos para habilitar la ejecución dinámica.

Para cualquier mnemotécnico que usa la estrategia dinámica, las estrategias de ejecución remota tomado de la marca --dynamic_remote_strategy, y las estrategias locales de la --dynamic_local_strategy. Aprobación --dynamic_local_strategy=worker,sandboxed establece el valor predeterminado de la configuración de ejecución dinámica para probar con trabajadores o la ejecución de zona de pruebas en el orden personalizado. Pasar --dynamic_local_strategy=Javac=worker anula el valor predeterminado para solo el nombre nemotécnico Javac. La versión remota funciona de la misma manera. Ambas marcas pueden especificar varias veces. Si una acción no se puede ejecutar localmente, es se ejecuten de forma remota como de costumbre, y viceversa.

Si tu sistema remoto tiene una caché, la marca --dynamic_local_execution_delay agrega un retraso en milisegundos a la ejecución local después de que el sistema remoto indicó un acierto de caché. Esto evita que se ejecute la ejecución local cuando más aciertos de caché más probables. El valor predeterminado es 1,000 ms, pero debería ajustarse para ser solo un poco más tiempo del que suelen tardar los aciertos de caché. La hora real depende tanto del control remoto y el tiempo que demora un recorrido de ida y vuelta. Por lo general, el valor será el mismo para todos los usuarios de un sistema remoto determinado, a menos que algunos estén lo suficientemente lejos para agregar latencia de ida y vuelta. Puedes usar la generación de perfiles de Bazel atributos para ver cuánto tiempo que toman los aciertos de caché.

La ejecución dinámica se puede usar con la estrategia de zona de pruebas local y con trabajadores persistentes. Los trabajadores persistentes ejecutarse con zona de pruebas cuando se usa con ejecución dinámica y no puede usar multiplex trabajadores. En los sistemas Darwin y Windows, la zona de pruebas la estrategia puede ser lenta; puedes pasar --reuse_sandbox_directories para reducir la sobrecarga de crear zonas de pruebas en estos sistemas.

La ejecución dinámica también puede ejecutarse con la estrategia standalone, aunque, como La estrategia standalone debe tomar el bloqueo de salida cuando comienza a ejecutarse. bloquea eficazmente la estrategia remota para que no finalice primero. El La marca --experimental_local_lockfree_output permite evitar este problema lo que permite que la ejecución local escriba directamente en la salida, pero que la anule y la ejecución remota, si esto debería terminar primero.

Si una de las ramas de la ejecución dinámica termina primero, pero es una falla, el falla toda la acción. Esta es una elección deliberada para evitar diferencias entre la ejecución local y remota.

Para obtener más información sobre cómo funciona la ejecución dinámica y su bloqueo, consulta Julio. El excelente blog de Merino publicaciones

¿Cuándo debo usar la ejecución dinámica?

La ejecución dinámica requiere algún tipo de sistema de ejecución remota. En este momento, no es posible utilizar un sistema remoto que solo incluya caché, como un error de caché se consideraría una acción fallida.

No todos los tipos de acciones son adecuados para la ejecución remota. Los mejores candidatos son los que son inherentemente más rápidos a nivel local, por ejemplo, a través de el uso de trabajadores persistentes o aquellos que se ejecutan rápido para que la sobrecarga de la ejecución remota domine el tiempo de ejecución. Desde cada acción ejecutada localmente bloquea una cantidad de recursos de CPU y memoria ejecutar acciones que no pertenecen a esas categorías simplemente retrasa la ejecución para aquellos que sí lo hacen.

Desde el lanzamiento 5.0.0-pre.20210708.4, la generación de perfiles de rendimiento contiene datos sobre la ejecución del trabajador, incluido el tiempo dedicado a finalizar una solicitud de trabajo después de perder una carrera de ejecución dinámica. Si ves subprocesos de trabajador de ejecución dinámica dedican mucho tiempo a adquirir recursos o a invertir async-worker-finish, es posible que tengas algunas acciones locales lentas que retrasan al trabajador conversaciones.

Cómo generar perfiles de datos con un rendimiento deficiente de ejecución dinámica

En el perfil anterior, que usa 8 trabajadores Javac, vemos muchos trabajadores Javac. perdieron las carreras y terminaron su trabajo en el async-worker-finish conversaciones. Esto se debe a que un mnemotécnico no trabajador que tomó suficientes recursos para retrasar a los trabajadores.

Cómo crear perfiles de datos con un mejor rendimiento de ejecución dinámica

Cuando solo se ejecuta Javac con ejecución dinámica, solo cerca de la mitad de terminan perdiendo la carrera después de comenzar su trabajo.

La marca --experimental_spawn_scheduler recomendada anteriormente dejó de estar disponible. Se activa la ejecución dinámica y se establece dynamic como la estrategia predeterminada para todos. mnemotécnicas que a menudo daría lugar a este tipo de problemas.

Rendimiento

El enfoque de ejecución dinámica supone que hay suficientes recursos disponibles de forma local y remota, que vale la pena invertir recursos adicionales para mejorar el rendimiento general. Sin embargo, el uso excesivo de recursos puede ralentizar a Bazel o la máquina en la que se ejecuta o aplicar una presión inesperada a un sistema remoto. Existen varias opciones para cambiar el comportamiento de la ejecución dinámica:

--dynamic_local_execution_delay retrasa el inicio de una sucursal local en un número de milisegundos después del inicio de la rama remota, pero solo si un acierto de caché remota durante la compilación actual. Esto hace que las compilaciones que se beneficien del almacenamiento en caché remoto no desperdician recursos locales cuando es probable que la mayoría los resultados de búsqueda en la caché. Según la calidad de la caché, Esto podría mejorar las velocidades de compilación, a costa de usar modelos de de Google Cloud.

--experimental_dynamic_local_load_factor es un recurso avanzado y experimental de administración de versiones. Para desactivar esta función, debe tener un valor de 0 a 1. Cuando se establece en un valor superior a 0, Bazel ajusta la cantidad de acciones programadas localmente cuando muchas acciones en espera pueden programarse. Si se establece en 1, se podrán programar tantas acciones como haya hay CPU disponibles (según --local_cpu_resources). Los valores más bajos establecen la cantidad de acciones programadas a un número menor de acciones a medida que aumenta la cantidad de acciones. que están disponibles para ejecutarse. Esto puede sonar contraintuitivo, pero con un buen control remoto de procesamiento, la ejecución local no es de mucha ayuda cuando se ejecutan muchas acciones y usar la CPU local para administrar acciones remotas.

--experimental_dynamic_slow_remote_time prioriza el inicio de las sucursales locales cuando la rama remota se ejecutó durante al menos este tiempo. Por lo general, el se le da prioridad a la acción programada más reciente, ya que tiene más probabilidades de pero si el sistema remoto a veces se bloquea o tarda más esto puede hacer que una compilación avance. Esta opción no está habilitada de forma predeterminada podría ocultar problemas con el sistema remoto que deberían solucionarse. Asegúrate de que para supervisar el rendimiento del sistema remoto si habilitas esta opción.

Se puede usar --experimental_dynamic_ignore_local_signals para permitir que el control remoto que una rama toma el control cuando un engendro local sale debido a una señal determinada. Este es es útil principalmente junto con los límites de recursos de los trabajadores (consulta --experimental_worker_memory_limit_mb, --experimental_worker_sandbox_hardening, y --experimental_sandbox_memory_limit_mb)), en las que los procesos de los trabajadores podrían finalizarse cuando usan demasiados recursos.

El perfil de seguimiento de JSON contiene un de gráficos relacionados con el rendimiento que pueden ayudar a identificar formas de mejorar el la compensación entre el rendimiento y el uso de recursos.

Soluciona problemas

Los problemas con la ejecución dinámica pueden ser sutiles y difíciles de depurar, ya que pueden el manifiesto solo con algunas combinaciones específicas de ejecución local y remota. El elemento --debug_spawn_scheduler agrega resultados adicionales de la ejecución dinámica. que ayuda a depurar esos problemas. También puedes ajustar el Marca de --dynamic_local_execution_delay y cantidad de trabajos remotos y locales para facilitan la reproducción de los problemas.

Si tienes problemas con la ejecución dinámica con standalone prueba correr sin --experimental_local_lockfree_output o ejecuta tu zona de pruebas de acciones locales. Esto puede ralentizar un poco la compilación (consulta la sección anterior si está en Mac o Windows), pero quita algunas de las posibles causas de errores.