todas tipos programacion parametros lenguaje las funciones else ejemplos dev con c++ caching c++11 c++14 cachegrind

tipos - ¿Cómo escribir un programa amistoso de caché de instrucciones en c++?



tipos de funciones en programacion (1)

Recientemente, Herb Sutter dio una gran charla sobre "C ++ moderno: lo que usted necesita saber" . El tema principal de esta charla fue la eficiencia y cómo importa la ubicación de los datos y el acceso a la memoria. También explicó cómo la CPU ataría el acceso lineal de la memoria (matriz / vector). Tomó un ejemplo de otra referencia clásica " Interpretación del juego de Bob Nystrom" sobre este tema.

Después de leer estos artículos, descubrí que hay dos tipos de caché que afectan el rendimiento del programa:

  1. Caché de datos
  2. Caché de instrucciones

La herramienta Cachegrind también mide la información de instrumentación del tipo de caché de nuestro programa. Los primeros puntos han sido explicados por muchos artículos / blogs y cómo lograr la buena eficacia del caché de datos (localidad de datos).

Sin embargo, no recibí mucha información sobre el Tema de caché de instrucciones y qué tipo de cosas deberíamos tener cuidado en nuestro programa para lograr un mejor rendimiento ?. Según mi entendimiento, nosotros (el programador) no tenemos mucho control sobre qué instrucción o qué orden se estaría ejecutando.

Sería muy bueno si los pequeños programas de c ++ explican cómo este contador (es decir, el caché de instrucciones) podría variar con nuestro estilo de programa de escritura. ¿Cuáles son las mejores prácticas que debe seguir el programador para lograr un mejor rendimiento con respecto a este punto?

Quiero decir que podemos entender sobre los temas de caché de datos si nuestro programa lo hace (vector vs list) de manera similar es posible explicar sobre el 2 ° punto. La intención principal de esta pregunta es comprender este tema tanto como sea posible.


Cualquier código que cambie el flujo de ejecución afecta al caché de instrucciones. Esto incluye llamadas de función y bucles, así como indicadores de función de desreferenciación.

Cuando se ejecuta una instrucción de salto o bifurcación, el procesador debe dedicar más tiempo a la decisión de si el código ya se encuentra en el caché de instrucciones o si necesita volver a cargar el caché de instrucciones (desde el destino de la bifurcación).

Por ejemplo, algunos procesadores pueden tener un caché de instrucciones lo suficientemente grande como para contener el código de ejecución para pequeños bucles. Algunos procesadores no tienen un caché de instrucciones grande y simplemente lo vuelven a cargar. La recarga de la memoria caché de instrucciones lleva tiempo que podría emplearse en la ejecución de instrucciones.

Busque estos temas:

  • Desenrollar
  • Ejecución de instrucción condicional (disponible en procesadores ARM)
  • Funciones en línea
  • Tubería de instrucciones

Edición 1: técnicas de programación para un mejor rendimiento
Para mejorar el rendimiento y reducir la recarga de la memoria caché de instrucciones, haga lo siguiente:

Reduzca las declaraciones "if" Diseñe su código para minimizar las declaraciones "if". Esto puede incluir Álgebra Booleana, usar más matemáticas o simplificar las comparaciones (¿realmente se necesitan?). Prefiere reducir el contenido de las cláusulas "entonces" y "demás" para que el compilador pueda usar las instrucciones del lenguaje de ensamblaje condicional.

Definir funciones pequeñas como inline o macros
Hay una sobrecarga asociada con las funciones de llamada, como almacenar la ubicación de retorno y volver a cargar el caché de instrucciones. Para funciones con una pequeña cantidad de sentencias, intente sugerir al compilador que se hagan en línea. Inlinear significa pegar el contenido del código donde está la ejecución, en lugar de hacer una llamada de función. Como se evita la llamada de función, también lo es la necesidad de volver a cargar el caché de instrucciones.

Desenrollar los bucles
Para iteraciones pequeñas, no buclee, pero repita el contenido del bucle (algunos compiladores pueden hacer esto en configuraciones de nivel de optimización más altas). Cuanto más contenido se repite, menos sucursales hay en la parte superior del ciclo y menos necesidad de volver a cargar el caché de instrucciones.

Utilice las búsquedas de tabla, no las declaraciones "si"
Algunos programas usan escalas "if-else-if" para mapear datos a valores. Cada instrucción "if" es un corte en la ejecución en el caché de instrucciones. A veces, con un poco de matemática, los valores se pueden colocar en una tabla como una matriz y el índice se calcula matemáticamente. Una vez que se conoce el índice, el procesador puede recuperar los datos sin interrumpir la caché de instrucciones.

Cambiar datos o estructuras de datos
Si el tipo de datos es constante, se puede optimizar un programa en torno a los datos. Por ejemplo, un programa que maneja paquetes de mensajes podría basar sus operaciones en base a las ID de paquetes (piense en una matriz de indicadores de funciones). Las funciones se optimizarían para el procesamiento de paquetes.

Cambie las listas vinculadas a matrices u otro contenedor de acceso aleatorio. Se puede acceder a los elementos de una matriz usando matemática y no interrumpir la ejecución. Las listas enlazadas deben atravesarse (bucle) para encontrar un elemento.