tipos sirve que para memoria funcion donde definicion caracteristicas cache aloja c++ c performance caching cpu-architecture

c++ - funcion - para que sirve la memoria cache



¿Cómo encontrar el tamaño del tamaño de la línea de caché L1 con mediciones de tiempo IO? (8)

Asigne una matriz de caracteres GRANDES (asegúrese de que sea demasiado grande para caber en la caché L1 o L2). Llénalo con datos aleatorios.

Comience a caminar sobre la matriz en pasos de n bytes. Haz algo con los bytes recuperados, como sumarlos.

Compare y calcule cuántos bytes / segundo puede procesar con diferentes valores de n , comenzando desde 1 y contando hasta 1000 o más. Asegúrese de que su punto de referencia imprima la suma calculada, por lo que el compilador posiblemente no pueda optimizar el código de referencia.

Cuando n == su tamaño de línea de caché, cada acceso requerirá leer una nueva línea en la caché L1. Por lo tanto, los resultados del índice de referencia deberían ser más lentos en ese momento.

Si la matriz es lo suficientemente grande, para cuando llegue al final, los datos al principio de la matriz ya estarán fuera de la memoria caché de nuevo, que es lo que desea. Entonces, después de incrementar n y comenzar de nuevo, los resultados no se verán afectados por la necesidad de tener los datos ya en la memoria caché.

Como tarea escolar, necesito encontrar la forma de obtener el tamaño de la línea de caché de datos L1, sin leer archivos de configuración ni usar llamadas de API. Se supone que debe usar la memoria para acceder a los tiempos de lectura / escritura para analizar y obtener esta información. Entonces, ¿cómo podría hacer eso?

En una prueba incompleta para otra parte de la tarea, para encontrar los niveles y el tamaño de la memoria caché, tengo:

for (i = 0; i < steps; i++) { arr[(i * 4) & lengthMod]++; }

Estaba pensando que tal vez solo necesito variar la línea 2, (i * 4) parte? Entonces, una vez que excedo el tamaño de la línea de caché, es posible que deba reemplazarlo, ¿qué tarda? Pero, ¿es tan directo? El bloque requerido puede estar ya en la memoria en alguna parte? O perpahs, ¿todavía puedo contar con el hecho de que si tengo unos steps suficientemente grandes, todavía funcionará con bastante precisión?

ACTUALIZAR

Aquí hay un intento en GitHub ... la parte principal debajo

// repeatedly access/modify data, varying the STRIDE for (int s = 4; s <= MAX_STRIDE/sizeof(int); s*=2) { start = wall_clock_time(); for (unsigned int k = 0; k < REPS; k++) { data[(k * s) & lengthMod]++; } end = wall_clock_time(); timeTaken = ((float)(end - start))/1000000000; printf("%d, %1.2f /n", s * sizeof(int), timeTaken); }

El problema es que no parece haber muchas diferencias entre los tiempos. FYI. ya que es para caché L1. Tengo TAMAÑO = 32 K (tamaño de la matriz)


Creo que debería ser suficiente para programar una operación que utiliza cierta cantidad de memoria. A continuación, aumente progresivamente la memoria (operandos, por ejemplo) utilizada por la operación. Cuando el rendimiento de la operación disminuye drásticamente, ha encontrado el límite.

Me gustaría simplemente leer un montón de bytes sin imprimirlos (la impresión afectaría tanto el rendimiento que se convertiría en un cuello de botella). Mientras se lee, el tiempo debería ser directamente proporcional a la cantidad de bytes leídos hasta que los datos ya no quepan en la L1, entonces obtendrá el golpe de rendimiento.

También debe asignar la memoria una vez al inicio del programa y antes de comenzar a contar el tiempo.


Creo que deberías escribir el programa, que recorrerá la matriz en orden aleatorio en lugar de derecho, porque el proceso moderno realiza la captación previa de hardware. Por ejemplo, make array of int, cuyos valores serán el número de la siguiente celda. Hice un programa similar hace 1 año http://pastebin.com/9mFScs9Z Lo siento por mi engish, no soy hablante nativo.


Eche un vistazo a Calibrator , todo el trabajo está protegido por derechos de autor, pero el código fuente está disponible gratuitamente. Desde su idea de document hasta el cálculo de los tamaños de las líneas de caché suena mucho más educado de lo que ya se ha dicho aquí.

La idea subyacente de nuestra herramienta de calibración es tener un micro benchmark cuyo desempeño solo dependa de la frecuencia de fallas de caché que ocurran. Nuestro calibrador es un simple programa en C, principalmente un pequeño bucle que ejecuta un millón de lecturas de memoria. Al cambiar la zancada (es decir, el desplazamiento entre dos accesos de memoria posteriores) y el tamaño del área de memoria, forzamos la variación de las tasas de error de caché.

En principio, la ocurrencia de fallas de caché está determinada por el tamaño de la matriz. Los tamaños de matriz que se ajustan a la memoria caché L1 no generan errores de caché una vez que los datos se cargan en la caché. Análogamente, las matrices que exceden el tamaño de la caché L1 pero que aún se ajustan a L2, causarán que L1 falle, pero no se produce un error en L2. Finalmente, las matrices mayores que L2 causan fallas L1 y L2.

La frecuencia de los fallos de caché depende de la zancada de acceso y del tamaño de la línea de caché. Con zancadas iguales o mayores que el tamaño de la línea de caché, se produce una falta de caché con cada iteración. Con zancadas más pequeñas que el tamaño de la línea de caché, una falla de caché ocurre solo en cada iteración (en promedio), donde n es el tamaño / zancada de la línea de caché de proporción.

Por lo tanto, podemos calcular la latencia de una falta de caché comparando el tiempo de ejecución sin errores con el tiempo de ejecución con exactamente una falla por iteración. Este enfoque solo funciona, si los accesos a la memoria se ejecutan de forma puramente secuencial, es decir, debemos asegurarnos de que ni dos o más instrucciones de carga ni el acceso a la memoria y el puro trabajo de la CPU puedan superponerse. Utilizamos un mecanismo de búsqueda de puntero simple para lograr esto: el área de memoria a la que accedemos se inicializa de modo que cada carga devuelve la dirección para la carga posterior en la siguiente iteración. Por lo tanto, las CPU súper-escalares no pueden beneficiarse de su capacidad de ocultar la latencia de acceso a la memoria mediante la ejecución especulativa.

Para medir las características de la memoria caché, ejecutamos nuestro experimento varias veces, variando la zancada y el tamaño de la matriz. Nos aseguramos de que la zancada varíe al menos entre 4 bytes y el doble del tamaño máximo esperado de la línea de caché, y que el tamaño de la matriz varíe de la mitad del tamaño de caché mínimo esperado a al menos diez veces el tamaño de caché máximo esperado.

Tuve que comentar #include "math.h" para compilarlo, después de eso encontré los valores de caché de mi computadora portátil correctamente. Tampoco pude ver los archivos de postscript generados.


Puede usar la función CPUID en el ensamblador, aunque no es portátil, le dará lo que desea.

Para los microprocesadores Intel, el tamaño de la línea de caché se puede calcular multiplicando bh por 8 después de llamar a la función cpuid 0x1.

Para los microprocesadores AMD, el tamaño de línea de caché de datos está en cl y la instrucción Tamaño de línea de caché está en dl después de llamar a la función cpuid 0x80000005.

Tomé esto de este artículo aquí .


Si te quedas atascado en el barro y no puedes salir, mira here .

Hay manuales y códigos que explican cómo hacer lo que está pidiendo. El código también es de muy alta calidad. Mira "Biblioteca de subrutinas".

El código y los manuales se basan en procesadores X86.


Solo una nota.

El tamaño de la línea de caché es variable en algunas familias de ARM Cortex y puede cambiar durante la ejecución sin notificaciones a un programa actual.


Vea cómo se implementa memtest86. Miden y analizan la velocidad de transferencia de datos de alguna manera. Los puntos de cambio de velocidad se corresponden con el tamaño de L1, L2 y el posible tamaño de caché L3.