2008-11-24 15 views
28

Estoy leyendo a través de K & R y llegué a la pequeña sección sobre variables de registro, y me preguntaba si las personas aquí tienen algunos buenos ejemplos de esto puesto en práctica.¿Cuál es un buen ejemplo de uso de variable de registro en C?

Desde la sección 4.7 en K & R:

La declaración de registro se parece a
int x registro;
registrar char c;

Para que quede claro, espero ver ejemplos de códigos geniales. Estoy (estoy bastante seguro de que) entiendo el tema, así que no sienta la necesidad de escribir una explicación detallada (a menos que lo desee).

Respuesta

64

No hay un buen ejemplo de uso de registros cuando se usan compiladores modernos (léase: últimos 15 años o más) porque casi nunca hace ningún bien y puede ser algo malo. Cuando usa register, le está diciendo al compilador "Sé cómo optimizar mi código mejor que usted", que casi nunca es el caso. Una de las tres cosas puede suceder cuando usa register:

  • El compilador lo ignora, esto es muy probable. En este caso, el único daño es que no puede tomar la dirección de la variable en el código.
  • El compilador hace honor a su solicitud y, como resultado, el código se ejecuta más lentamente.
  • El compilador hace honor a su solicitud y el código se ejecuta más rápido, este es el escenario menos probable.

Incluso si un compilador produce un mejor código cuando usa el registro, no hay razón para creer que otro hará lo mismo. Si tiene algún código crítico que el compilador no está optimizando lo suficiente, probablemente su mejor opción sea utilizar el ensamblador para esa parte de todos modos, pero, por supuesto, hacer un perfil adecuado para verificar primero que el código generado sea realmente un problema.

+3

"¿Pueden pasar tres cosas y dos son malas?" ¿Dónde lo he escuchado antes ... ;-) –

+0

Recuerde que el compilador puede ignorar su sugerencia de manera perfecta, no hay nada en el estándar que indique que tiene que poner una variable de registro en un registro. –

+0

también podría ser el caso de que escriba un compilador de fondo y diga "registro" para todos los lugareños en una función hará una función sin apilamiento. eso sería bastante útil, creo. –

10

En general estoy de acuerdo con Robert, pero como cualquier buena regla, esta también tiene excepciones.
Si trabaja en un sistema profundamente integrado, es posible que sepa mejor que el compilador cómo optimizar el código para su aplicación específica en su arquitectura de hardware específica.

Pero en el 99% de los casos la explicación de Roberts es buena para la palabra incrustada también.

+2

Esto se parece mucho a lo que dijo Robert, con toda honestidad. –

+0

En realidad tienes razón. Releí la publicación y el último párrafo aclara lo que quería aclarar ... La próxima vez leeré mejor – Ilya

3

Otro caso común es cuando se implementan intérpretes de bajo nivel. Mantener algún estado en registros, ej. puntero de pila de la máquina virtual, puede reducir significativamente el acceso a la memoria y acelerar tu código.

Consulte vmgen — a generator of efficient virtual machine interpreters para obtener un ejemplo de la optimización (5.2 Almacenamiento en la parte superior de la pila).

1

primero, la variable de registro debe utilizarse para variables muy utilizadas, como la variable de control de bucle para mejorar el rendimiento al minimizar el tiempo de acceso.secundario puede usar solo y solo registrar el especificador de almacenamiento en esta situación like, fun (auto int a, auto int b): error fun (registrar int a, registrar int b): justo esto se ejecutará fun (estático) int a, static int b): error fun (extern int a, extern int b): error

+3

¿Qué? El texto de K & R es de la década de 1970, por lo que algunas de sus recomendaciones están un poco desactualizadas. Usar 'register' es definitivamente uno de esos. –

4

Sé que esto es de bastante tiempo, pero aquí hay una implementación de un subprocedimiento de heapsort en el que el uso de registrar las variables hace que el algoritmo más rápido, al menos usando gcc 4.5.2 para compilar el código

inline void max_heapify(int *H, int i){ 
    char OK = FALSE; 
    register int l, r, max, hI; 
    while(!OK){ 
     OK = TRUE; 
     l = left(i); 
     r = right(i); 
     max = i; 
     if(l <= H[SIZE] && H[l] > H[i]){ 
      max = l; 
     } 
     if(r <= H[SIZE] && H[r] > H[max]){ 
      max = r; 
     } 
     if(max != i){ 
      OK = FALSE; 
      hI = H[i]; 
      H[i] = H[max]; 
      H[max] = hI; 
      i = max; 
     } 
    } 
} 

probé el algortihm con y w sin la palabra reservada del registro antes de los atributos y lo ejecuté para clasificar una matriz al azar con 50,000,000 elementos en mi cuaderno, algunas veces para cada versión.

el uso de registros disminuyó el tiempo de la colección desde ~ 135s a ~ 125s.

También probé con 5,000,000 elementos solamente, pero lo ejecuté más veces.

La versión sin el registro comenzó a 11s pero cada ejecución rebajado el tiempo hasta llegar a 9,65s y se detuvo en ella

la versión con el registro comenzó en el 10s y bajó el tiempo hasta 8,80s.

Creo que tiene algo que ver con la memoria caché. Sin embargo, parece que los registros hacen que el algoritmo sea más rápido por un factor constante

Dado que estas variables son bastante utilizadas a lo largo del algoritmo, al asegurarse de que están en el registro en lugar de dejar este trabajo para el compilador se obtiene un mejor resultado en este caso. Sin embargo, no mejoró tanto el tiempo.

Espero que sea útil para alguien, saludos.

+3

Para tomar su evaluación comparativa en serio, debe proporcionar información acerca de cómo compiló (qué indicadores), en qué plataforma lo hizo, y tal vez algunos detalles sobre su arquitectura y/o CPU. Cómo ejecutó max_heapify también es importante. – raylu

Cuestiones relacionadas