Gráfico de dependencia en el diseño del compilador

Se utiliza un gráfico de dependencia para representar el flujo de información entre los atributos en un árbol de análisis. En un árbol de análisis, un gráfico de dependencia básicamente ayuda a determinar el orden de evaluación de los atributos. El objetivo principal de los gráficos de dependencia es ayudar al compilador a verificar varios tipos de dependencias entre declaraciones para evitar que se ejecuten en la secuencia incorrecta, es decir, de una manera que afecte el significado del programa. Este es el aspecto principal que ayuda a identificar los numerosos componentes paralelizables del programa.

Nos ayuda a determinar el impacto de un cambio y los objetos que se ven afectados por él. Dibujar bordes para conectar acciones dependientes se puede usar para crear un gráfico de dependencia. Estos arcos dan como resultado un ordenamiento parcial entre las operaciones y también evitan que un programa se ejecute en paralelo. Aunque el enstringmiento de definición de uso es un tipo de análisis de dependencia, da como resultado estimaciones de confianza de datos excesivamente cautelosas. En una ruta de control compartido, puede haber cuatro tipos de dependencias entre las sentencias I y j.

Los gráficos de dependencia, al igual que las redes dirigidas por otros, tienen Nodes o vértices representados como cuadros o círculos con nombres, así como flechas que los unen en su dirección transversal obligatoria. Los gráficos de dependencia se usan comúnmente en la literatura científica para describir vínculos semánticos, dependencias temporales y causales entre eventos y el flujo de corriente eléctrica en circuitos electrónicos. Dibujar gráficos de dependencia es tan común en las ciencias de la computación que queremos emplear herramientas que automaticen el proceso en función de algunas instrucciones textuales básicas de parte nuestra.

Tipos de dependencias:

Las dependencias se clasifican en términos generales en las siguientes categorías:

1. Dependencias de datos: 

Cuando una declaración calcula datos que luego son utilizados por otra declaración. Un estado en el que la instrucción debe esperar un resultado de una instrucción anterior antes de que pueda completar su ejecución. Una dependencia de datos provocará una interrupción en los servicios de flujo de una tubería de procesador o bloqueará la emisión paralela de instrucciones en un procesador superescalar en procesadores de alto rendimiento que utilizan enfoques superescalares o de tubería.

2. Dependencias de control: 

Las dependencias de control son aquellas que provienen del flujo de control bien ordenado de un programa. Un escenario en el que una instrucción de programa se ejecuta si la instrucción anterior se evalúa de una manera que le permite ejecutarse se conoce como dependencia de control.

3. Dependencia del flujo:

En informática, se produce una dependencia de flujo cuando una declaración de programa se refiere a los datos de una declaración anterior.

4. Antidependencia: 

Cuando una instrucción necesita un valor que luego se modifica, esto se conoce como antidependencia o escritura después de lectura (WAR) . La instrucción 2 anti-depende de la instrucción 3 en el siguiente ejemplo; el orden de estas instrucciones no se puede modificar, ni se pueden realizar en paralelo (cambiando potencialmente el orden de las instrucciones), porque esto modificaría el valor final de A.

5. Dependencia del producto: 

Una dependencia de salida, también conocida como escritura tras escritura (WAW) , ocurre cuando la secuencia en la que se ejecutan las instrucciones tiene un impacto en el valor final de salida de la variable. Hay una dependencia de salida entre las instrucciones 3 y 1 en el siguiente ejemplo; alterar el orden de las instrucciones afectaría el valor final de A, por lo que estas instrucciones no se pueden ejecutar en paralelo.

6. Control-Dependencia: 

Si el resultado de A determina si se debe ejecutar B o no, una instrucción B tiene una dependencia de control de una instrucción A anterior. La instrucción de estilo de visualización S 2S 2 tiene una dependencia de control de la instrucción de estilo de visualización S 1S 1 en el siguiente ejemplo . Sin embargo, el estilo de visualización S 3S 3 no depende del estilo de visualización S 1S 1, porque el estilo de visualización S 3S 3 siempre se realiza independientemente del resultado del estilo de visualización S 1S 1.

Ejemplo de gráfico de dependencia:

Diseñe un gráfico de dependencia para la siguiente gramática:

E -> E1 + E2
E -> E1 * E2 
                     PRODUCCIONES                                        REGLAS SEMÁNTICAS                    

E -> E1 + E2

E -> E1 * E2 

E.val -> E1.val + E2.val

E.val -> E1.val * E2.val

El gráfico de dependencia requerido para la gramática anterior se representa como:

Gráfico de dependencia para el ejemplo anterior

  1. Los atributos sintetizados están representados por .val .
  2. Por lo tanto, E.val , E1.val y E2.val tienen atributos sintetizados.
  3. Las dependencias se muestran con flechas negras.
  4. Las flechas de E1 y E2 muestran que el valor de E depende de E1 y E2.

Resolución de dependencia:

La resolución de dependencias es un procedimiento de dos fases que se realiza hasta que se completa el gráfico de dependencias.

  1. Realice la resolución de conflictos cuando se introduzca una nueva dependencia en el gráfico para decidir qué versión se debe agregar.
  2. En una dependencia específica, por ejemplo, un módulo versionado, que se identifica como parte del gráfico, ayuda a extraer su información para que ayude a agregar sus dependencias una por una.

Al realizar la resolución de dependencias, Gradle (herramienta de automatización) maneja dos tipos de conflictos:

Conflictos de versión:

Un conflicto de versión es un conflicto que ocurre cuando dos componentes dependen del mismo módulo pero las versiones son diferentes.

Por ejemplo: 

Digamos que el proyecto depende de la biblioteca de reacción de Facebook, es decir, «com.google.react: react:18.7.0». aquí la versión es 18.7.0. Ahora podemos ver claramente que también depende de alguna otra biblioteca que a su vez depende de reaccionar, pero la versión 19.0.2 es completamente diferente.

Gradle resuelve esto seleccionando la versión más alta. En ese caso, se elegirá 19.0.2. 

Pero ese no es el final de la tienda. Gradle tiene una noción de declaración de versión enriquecida, y existen numerosas formas de elegir una versión entre una variedad de opciones.

Conflictos de implementación:

Los conflictos de implementación son las situaciones en las que el gráfico de dependencia contiene varios módulos que proporcionan la misma implementación o capacidad en la terminología de Gradle. Gradle determina lo que ofrece un módulo usando variaciones y capacidades. Esta es una característica única en su tipo que exige su propio capítulo para comprender completamente lo que implica y permite. Se produce un conflicto en el momento en que dos módulos:

  1. Intentar seleccionar variantes incompatibles,
  2. Declarar la misma capacidad

Usos del gráfico de dependencia:

  1. La idea principal detrás de los gráficos de dependencia es que el compilador verifique varios tipos de dependencias entre declaraciones para evitar que se ejecuten en la secuencia incorrecta, es decir, de una manera que afecte el significado del programa.
  2. Esto lo ayuda a identificar los numerosos componentes paralelizables del programa.
  3. Instaladores de software automatizados: recorren el gráfico buscando paquetes de software que se necesitan pero que aún no se han instalado. El acoplamiento de los paquetes determina la confianza.
  4. La programación de instrucciones utiliza la dependencia de una manera más amplia.
  5. Los gráficos de dependencia se utilizan ampliamente en la eliminación de código muerto .

Publicación traducida automáticamente

Artículo escrito por vipul1501 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *