stringtranslate.com

Alias ​​(informática)

En informática , el alias describe una situación en la que se puede acceder a una ubicación de datos en la memoria a través de diferentes nombres simbólicos en el programa. Por lo tanto, modificar los datos a través de un nombre modifica implícitamente los valores asociados con todos los nombres con alias, lo que puede no ser esperado por el programador. Como resultado, el aliasing hace que sea particularmente difícil comprender, analizar y optimizar programas. Los analizadores de alias tienen como objetivo generar y calcular información útil para comprender el alias en los programas.

Ejemplos

Desbordamiento del búfer

Por ejemplo, la mayoría de las implementaciones del lenguaje de programación C no realizan la verificación de los límites de la matriz . Luego se puede explotar la implementación del lenguaje de programación por parte del compilador y las convenciones del lenguaje ensamblador de la arquitectura de la computadora , para lograr efectos de alias escribiendo fuera de la matriz (un tipo de desbordamiento del búfer ). Esto invoca un comportamiento indefinido según la especificación del lenguaje C; sin embargo, muchas implementaciones de C mostrarán los efectos de alias descritos aquí.

Si se crea una matriz en la pila , con una variable dispuesta en la memoria directamente al lado de esa matriz , se podría indexar fuera de la matriz y cambiar directamente la variable cambiando el elemento relevante de la matriz. Por ejemplo, si hay una intmatriz de tamaño 2 (para este ejemplo, llámela arr), junto a otra intvariable (llámela i), arr[2](es decir, el tercer elemento) se le asignará un alias isi son adyacentes en la memoria.

# incluir <stdio.h>  int principal () { int arreglo [ 2 ] = { 1 , 2 }; int yo = 10 ;           /* Escribe más allá del final de arr. El comportamiento indefinido en C estándar se escribirá en i en algunas implementaciones. */ arreglo [ 2 ] = 20 ;    printf ( "elemento 0: %d \t " , arreglo [ 0 ]); // genera 1 printf ( "elemento 1: %d \t " , arr [ 1 ]); // genera 2 printf ( "elemento 2: %d \t " , arr [ 2 ]); // genera 20, si se produjo un alias printf ( "i: %d \t\t " , i ); // también podría generar 20, no 10, debido al alias, pero el compilador podría tener i almacenado en un registro e imprimir 10 /* el tamaño del arreglo sigue siendo 2. */ printf ( "tamaño del arreglo: %lu \n " , ( largo ) ( tamaño de ( arr ) / tamaño de ( int ))); }                 

Esto es posible en algunas implementaciones de C porque una matriz es un bloque de memoria contigua y los elementos de la matriz simplemente están referenciados por desplazamientos de la dirección del comienzo de ese bloque multiplicada por el tamaño de un solo elemento. Dado que C no tiene límites de verificación, es posible indexar y direccionar fuera de la matriz. Tenga en cuenta que el comportamiento de alias antes mencionado es un comportamiento indefinido . Algunas implementaciones pueden dejar espacio entre matrices y variables en la pila, por ejemplo, para alinear variables con ubicaciones de memoria que son múltiplos del tamaño de palabra nativo de la arquitectura . El estándar C generalmente no especifica cómo se deben distribuir los datos en la memoria. (ISO/IEC 9899:1999, sección 6.2.6.1).

No es erróneo que un compilador omita los efectos de alias para los accesos que quedan fuera de los límites de una matriz.

punteros alias

Otra variedad de alias puede ocurrir en cualquier idioma que pueda hacer referencia a una ubicación en la memoria con más de un nombre (por ejemplo, con punteros ). Este es un problema común con funciones que aceptan argumentos de puntero, y su tolerancia (o la falta de ella) al alias debe documentarse cuidadosamente, particularmente para funciones que realizan manipulaciones complejas en áreas de memoria que se les pasan.

Alias ​​especificado

En algunos casos, puede ser deseable un comportamiento de alias controlado (es decir, un comportamiento de alias que se especifica, a diferencia del que permite el diseño de memoria en C). Es una práctica común en Fortran . El lenguaje de programación Perl especifica, en algunas construcciones, un comportamiento de alias, como en los bucles. Esto permite modificar ciertas estructuras de datos directamente con menos código. Por ejemplo,foreach

mi @array = ( 1 , 2 , 3 );     foreach my $element ( @array ) { # Incrementa $element, modificando así automáticamente # @array, ya que $element tiene un ''alias'' # para cada uno de los elementos de @array por turno. $elemento ++ ; }        imprimir "@matriz\n" ; 

imprimirá "2 3 4" como resultado. Si uno quisiera evitar los efectos de alias, podría copiar el contenido de la variable de índice en otra y cambiar la copia.

Conflictos con la optimización

Los optimizadores a menudo tienen que hacer suposiciones conservadoras sobre las variables cuando es posible el alias. Por ejemplo, conocer el valor de una variable (como x5) normalmente permite ciertas optimizaciones (como la propagación constante ). Sin embargo, el compilador no puede utilizar esta información después de una asignación a otra variable (por ejemplo, en C, *y = 10) porque podría ser *yun alias de x. Este podría ser el caso después de una tarea como y = &x. Como efecto de esta asignación a *y, el valor de xtambién cambiaría, por lo que propagar la información que xes 5 a las declaraciones siguientes *y = 10sería potencialmente incorrecto (si *yde hecho es un alias de x). Sin embargo, si hay información sobre punteros, el proceso de propagación constante podría generar una consulta como: ¿puede xser un alias de *y? Entonces, si la respuesta es no, x = 5se podrá propagar de forma segura.

Otra optimización afectada por el alias es la reordenación del código. Si el compilador decide que xno tiene el alias de *y, entonces el código que usa o cambia el valor de xse puede mover antes de la asignación *y = 10, si esto mejoraría la programación o permitiría realizar más optimizaciones de bucle .

Para permitir tales optimizaciones de manera predecible, el estándar ISO para el lenguaje de programación C (incluida su edición más reciente C99 , consulte la sección 6.5, párrafo 7) especifica que es ilegal (con algunas excepciones) acceder a la misma ubicación de memoria utilizando punteros de diferentes tipos. Por lo tanto, un compilador puede suponer que dichos punteros no tienen alias. Esta regla, conocida como regla de alias estricta , a veces permite aumentos impresionantes en el rendimiento, [1] pero se sabe que rompe algún código que de otro modo sería válido. Varios proyectos de software violan intencionalmente esta parte del estándar C99. Por ejemplo, Python 2.x lo hizo para implementar el recuento de referencias , [2] y requirió cambios en las estructuras de objetos básicas en Python 3 para permitir esta optimización. El kernel de Linux hace esto porque el alias estricto causa problemas con la optimización del código en línea. [3] En tales casos, cuando se compila con gcc-fno-strict-aliasing , se invoca la opción para evitar optimizaciones no deseadas que podrían generar código inesperado.

Alias ​​de hardware

El término alias también se utiliza para describir la situación en la que, debido a una elección de diseño de hardware o a una falla del hardware, uno o más de los bits de dirección disponibles no se utilizan en el proceso de selección de memoria. [4] Esto puede ser una decisión de diseño si hay más bits de dirección disponibles de los necesarios para admitir los dispositivos de memoria instalados. En una falla, uno o más bits de dirección pueden estar en cortocircuito o pueden ser forzados a tierra (0 lógico) o al voltaje de suministro (1 lógico).

Ejemplo

Para este ejemplo, supongamos un diseño de memoria con 8 ubicaciones, que requiere solo 3 líneas de dirección (o bits ), ya que 2 · 3 = 8). Los bits de dirección (llamados A2 a A0) se decodifican para seleccionar ubicaciones de memoria únicas de la siguiente manera, en forma de contador binario estándar :

En la tabla anterior, cada una de las 8 combinaciones únicas de bits de dirección selecciona una ubicación de memoria diferente. Sin embargo, si un bit de dirección (digamos A2) fuera puesto en cortocircuito a tierra, la tabla se modificaría de la siguiente manera:

En este caso, siendo A2 siempre cero, las primeras cuatro ubicaciones de memoria se duplican y aparecen nuevamente como las segundas cuatro. Las ubicaciones de memoria 4 a 7 se han vuelto inaccesibles.

Si este cambio se produjera en un bit de dirección diferente, los resultados de la decodificación serían diferentes, pero en general el efecto sería el mismo: la pérdida de un único bit de dirección corta el espacio de memoria disponible a la mitad, con la consiguiente duplicación (aliasing) del bit de dirección. espacio restante.

Ver también

Referencias

  1. ^ Mike Acton (1 de junio de 2006). "Comprensión del alias estricto".
  2. ^ Neil Schemenauer (17 de julio de 2003). "Alias ​​estricto ANSI y Python".
  3. ^ Linus Torvalds (26 de febrero de 2003). "Re: Compilación no válida sin -fno-strict-aliasing".
  4. ^ Michael Barr (27 de julio de 2012). "Pruebas de memoria basadas en software".

enlaces externos