Pregunta

Esto es parte de salida Cachegrind. Esta parte del código ha sido ejecutado por 1224 veces. elmg1 es una matriz de largo sin signo de tamaño 16 x 20. Mi máquina L1 tamaño de la caché es de 32 KB, 64B tamaño de línea de caché y de 8 vías conjunto asociativo.

  1. for (i = 0; i <20; i ++) 78 336 2448 2 50 184 0 0 1224 0 0
  2. {
  3. telm01 = elmg1 [i]; 146 880 0 0 73 440 0 0 24 480 0 0
  4. telm31 = (telm01 << 3) ^ val1; 97.920 0 0 48.960 0 0 24.480 0 0
  5. telm21 = (telm01 << 2) ^ (val1 >> 1); 146 880 1224 1 48 960 0 0 24 480 0 0
  6. telm11 = (telm01 << 1) ^ (val1 >> 2); 146 880 0 0 48 960 0 0 24 480 0 0
  7. }

A. La razón por la que he puesto aquí, es que en la tercera línea dentro del bucle, veo una serie de fallos I1 (una L2 se pierda así). Es algo es confuso y no podía adivinar la razón por qué?

B. Estoy tratando de optimizar (tiempo) una porción de código. Lo anterior es sólo un pequeño fragmento. Creo que en mi programa de acceso a la memoria una me cuesta mucho. Como en el ejemplo anterior elmg1 es una matriz de 16 x 20 tamaño de largos sin signo. Cuando trato de usarlo en el código, siempre hay algunos fallos, y en mi programa de estas variables se producen una gran cantidad. ¿Alguna sugerencia?

C. Necesito asignar y (a veces inicializar) estos largos sin signo. ¿Puede sugerir cuál debería preferir, calloc o declaración de matriz y la inicialización explícita a continuación. Por cierto habrá ninguna diferencia en las manijas de manera caché ellos?

Gracias.

¿Fue útil?

Solución

¿Has probado a desenrollar el bucle?

  1. No me preocuparía pierde L1 en este momento. También se pierda L2 de 1224 veces está bien, la CPU tiene que cargar los valores en la memoria caché en algún momento.
  2. ¿Qué porcentaje de L2 pierde cuesta este código en comparación con el resto del programa?
  3. Uso calloc (), si el tamaño de la matriz es siempre la misma y se utiliza constantes para el tamaño, el compilador puede optimizar el zero'ing de la matriz. También es la única cosa que pudiera afectar los usos líneas de caché es la alineación, no cómo se initizliated.

editar:. El número donde difícil de leer de esa manera y las leyó mal la primera vez

le permite asegurarse de que yo estoy leyendo los números de la derecha de la línea 5:

Ir    146,880
I1mr  1,224
ILmr  1
Dr    48,960
D1mr  0
DLmr  0
Dw    24,480
D1mw  0
DLmw  0

La caché de L1 se divide en dos 32Kbyte almacena en caché uno para código I1 y uno de los datos D1. IL y DL son la L2 o L3 caché que es compartida por los datos y las instrucciones.

El gran número de I1mr es pierde instrucción no se pierde de datos, esto significa que el código de bucle está siendo expulsado de la memoria caché de instrucciones I1.

I1 pierde en la línea 1 y 5 en total 3672 que es 3 veces 1224, por lo que cada vez que se ejecuta el bucle que obtiene 3 I1 fallos de caché con líneas de caché 64Byte Eso significa que el tamaño del código de bucle está entre 128-192 bytes para cubrir 3 líneas de caché. Así que esos I1 pierde en la línea 5 es porque es allí donde el código de bucle cruza la última línea de caché.

yo recomendaría usar KCachegrind para la visualización de los resultados de Cachegrind

Editar:. Más sobre líneas de caché

Ese código de bucle no se ve como que está siendo llamado 1224 veces por sí mismo, por lo que significa que hay más código que está empujando el código fuera de la caché I1.

Su caché 32Kbyte I1 se divide en 512 líneas de caché (64bytes cada uno). Los medios de parte "de 8 vías conjunto asociativo" que cada dirección de memoria está asignado a sólo 8 de las 512 líneas de caché. Si todo el programa que está a una cuadra perfil era continua de 32Kbytes de memoria, entonces todo encaja en la memoria caché I1 y ninguno sería expulsado. Ese no es el caso mostlikely y habrá más de 8 bloques de código 64byte contentándose por las mismas 8 líneas de caché. Digamos que todo su programa tiene 1Mbyte de código (esto incluye las bibliotecas), entonces cada grupo de 8 líneas de caché tendrá cerca de 32 (1 Mbyte / 32Kbyte) piezas de código contentándose para esos mismos 8 líneas de caché.

Leer este artículo lwn.net para todos los detalles morbosos sobre la CPU cachés

El compilador no siempre puede detectar qué funciones del programa serán puntos de acceso (llamado muchas veces) y que será codespots (es decir, código de tratamiento de errores, que casi nunca funciona). GCC ha atributos de la función frío / calor que le permitirá a las funciones de calificación, ya frío / calor, esto permitirá que el compilador para agrupar las funciones calientes juntos en un bloque de memoria para obtener un mejor uso de la caché (es decir, código de frío no estará empujando hotcode de los cachés).

De todas formas esas I1 pierde son realmente no vale la pena el tiempo para preocuparse.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top