|
Bloqueo bucle es una combinación de exploración y bucle división interchange a fin de mejorar la reutilización de datos locales. Ayuda a la bucles anidados que procesan las matrices de memoria y son demasiado grandes como para caber en la caché. El bucle bloqueo permite reutilizar la transformación de los bucles de matrices como para que la matriz transformado bucles bandas que se adaptan manipular en la caché. De hecho, un bucle bloqueado utiliza array elements en las secciones que están óptima para que se ajuste tamaño en la memoria caché.
Usar caché que bloquean para acordar un bucle de manera que se ejecutan del mismo muchos cálculos que sea posible en datos ya que residen en la memoria caché. (El siguiente bloque de los datos no se leen en caché hasta utilizando la primera bloque cálculos haya finalizado.)
El bucle es parte del bloqueo HLO optimización del fase en Intel compiler y está disponible cuando se utiliza compilador opción - O3. El compilador heurística utiliza predeterminado para el bucle bloqueo. No obstante, también puede utilizar /Qopt-bloqueo Placa:n en Windows o -anticipadas bloqueo Placa:n en Linux para especificar bucle factor bloqueo.
Los datos reutilización:
La reutilización datos es importante comprender que bloquean. Existen dos tipos de datos asociados con la reutilización bloqueo bucle:
- Capacidad para volver a emplear
- La reutilización temporal
Capacidad para volver a emplear
Capacidad para volver a emplear utiliza los datos que se encached como resultado de buscar otro tipo de datos de la memoria. Los datos se obtengan las líneas una caché a la vez. Esto es 64 bytes de los Intel(R) core2 procesadores. Si los datos solicitados se encuentra en el principio de la línea de caché (alineado datos), y el resto de la línea de caché subsiguiente contiene elementos matriz después para float matriz, esto significa que el elemento y los siete elementos siguientes son almacenadas en caché en cada prefetch después de la primera. Si algunos de estos elementos podría a continuación, siete utilizarse en cualquier repeticiones de la bucle, la capacidad para volver a emplear sería aprovechando. Pasos de bucles con mayor que uno, capacidad para volver a emplear aún puede ocurrir. No obstante, la memoria caché líneas contienen los elementos menos utilizable.
La reutilización temporal
La reutilización temporales utiliza el mismo artículo de datos en más de una iteración del bucle. Si el bucle utiliza el mismo elemento en subsiguiente iteraciones bucle exhibiciones temporales bucle a continuación, reutilizar en el contexto de la bucle. Capacidad para volver a emplear el bloqueo aprovecha al máximo al garantizar que, una vez obtengan, la memoria caché líneas no se sobrescriben hasta que su capacidad para volver a emplear sale.
Ejemplo 1: simple bucle bloqueo
El ejemplo siguiente demuestra el bloqueo bucle simple. El bucle bloqueo permite que las matrices A y B para ser bloqueado fin en porciones de modo que el tamaño combinado de total dos bloqueado (A y B) porciones es más pequeño que tamaño de la memoria caché, lo que puede mejorar la reutilización datos.
// Before_loopblocking.cpp
/*
*Icl /Qoption,link,"/PILA:1000000000" before_loopblocking.cpp
*/
#Incluir < tiempo.h>
#Incluir < stdio.h>
#Define MAX 8000
Void agregar( int a[][MAX], int b[][MAX]);
Int main()
{
Int i, j;
Int A[MAX][MAX];
Int B[MAX][MAX];
Clock_tantes, después;
Inicializar matriz http://support.intel.com/.
Para(i=0;i<MAX;i++).
{
Para(j=0;j<MAX; j++).
{
A[i][j]=j;
B[i][j]=j;
}
}
= Reloj antes();
Agregar(A, B);
Agregar(A, B);
Agregar(A, B);
Agregar(A, B);
= Reloj después();
Printf("\nTime toma para completar : %7.2lf segundos\n" ,( float)(después de - antes)/ CLOCKS_PER_SEC); // lista tiempo toma para completar agregar funciona
}
Void agregar( int a[][MAX], int b[][MAX])
{
Int i, j;
Para(i=0;i<MAX;i++).
{
Para(j=0; j<MAX;j++).
{
A[i][j] = a[i][j] + b[j][i]; si agrega dos matrices
}
}
}
La anterior código es modificada a continuación para mejorar la reutilización de los datos almacenados en caché:
// After_loopblocking.cpp
/*
*Icl /Qoption,link,"/PILA:1000000000" after_loopblocking.cpp
*/
#Incluir < stdio.h>
#Incluir < tiempo.h>
#Define MAX 8000
16 BS #definesi tamaño de bloque bucle es el valor seleccionado como bloqueo formato.
Void agregar( int a[][MAX], int b[][MAX]);
Int main()
{
Int i, j;
Int A[MAX][MAX];
Int B[MAX][MAX];
Clock_tantes, después;
Inicializar matriz http://support.intel.com/.
Para(i=0;i<MAX;i++).
{
Para(j=0;j<MAX; j++).
{
A[i][j]=j;
B[i][j]=j;
}
}
= Reloj antes();
Agregar(A, B);
Agregar(A, B);
Agregar(A, B);
Agregar(A, B);
= Reloj después();
Printf("\nTime toma para completar : %7.2lf segundos\n" ,( float)(después de - antes)/ CLOCKS_PER_SEC); // lista tiempo toma para completar agregar funciona
}
Void agregar( int a[][MAX], int b[][MAX])
{
Int i, j, ii, jj;
Para(i=0;i<MAX;i+=BS)
{
Para(j=0; j<MAX;j+=BS)
{
Para(ii=i; ii<i+BS; ii++)bucle externas en inglés)
{
Para(jj=j; jj<j+BS; jj++).
{
Una matriz http://support.intel.com/. B experiencias caché
En inglés) para cada iteración de bucle externas
A[ii][jj] = a[ii][jj] + b[jj][ii];}
}
}
}
}
Ejemplo 2: complejas bloqueo
// Matrixmul.cpp
/*
*Icl /Qoption,link,"/PILA:1000000000" matrixMul.cpp
*/
#Incluir < stdio.h>
#Incluir < tiempo.h>
#Define MAX 800
Void matmul( int c[][MAX], int a[][MAX], int b[][MAX]);
Int main()
{
Int i, j;
Int A[MAX][MAX];
Int B[MAX][MAX];
Int C[MAX][MAX];
Clock_tantes, después;
Inicializar matriz http://support.intel.com/.
Para(i=0;i<MAX;i++).
{
Para(j=0;j<MAX; j++).
{
A[i][j]=j;
B[i][j]=j;
}
}
= Reloj antes();
Matmul(C, A, B);
= Reloj después();
Printf("\nTime toma para completar : %7.2lf segundos\n" ,( float)(después de - antes)/ CLOCKS_PER_SEC); // lista tiempo toma para completar agregar funciona
}
Void matmul( int c[][MAX], int a[][MAX], int b[][MAX])
{
Int i, j, k;
Para(i=0;i<MAX;i++).
{
Para(j=0; j<MAX;j++).
{
Para(k=0; k < MAX; k++).
{
C[i][j] = c[i][j] + a[i][k] * b[k][j];
}
}
}
}
Los anteriores se modifican código a continuación espacial y temporal para mejorar la reutilización de los datos almacenados en caché de matriz a, b y c:
// Matrixmulblk.cpp
/*
*Icl /Qoption,link,"/PILA:1000000000" matrixMulBlk.cpp
*/
#Incluir < stdio.h>
#Incluir < tiempo.h>
#Define MAX 800
16 BS #definesi tamaño de bloque bucle es el valor seleccionado como bloqueo formato.
Void matmul( int c[][MAX], int a[][MAX], int b[][MAX]);
Int main()
{
Int i, j;
Int A[MAX][MAX];
Int B[MAX][MAX];
Int C[MAX][MAX];
Clock_tantes, después;
Inicializar matriz http://support.intel.com/.
Para(i=0;i<MAX;i++).
{
Para(j=0;j<MAX; j++).
{
A[i][j]=j;
B[i][j]=j;
}
}
= Reloj antes();
Matmul(C, A, B);
= Reloj después();
Printf("\nTime toma para completar : %7.2lf segundos\n" ,( float)(después de - antes)/ CLOCKS_PER_SEC); // lista tiempo toma para completar agregar funciona
}
Void matmul( int c[][MAX], int a[][MAX], int b[][MAX])
{
Int i, j, k, jj, kk;
Para(j=0;j<MAX; j += BS)
{
Para(k=0; k<MAX; k += BS)
{
Para(i=0; i < MAX, he++).
{
Para(kk=k; kk<k+BS; kk++).
{
Para(jj=j; jj<j+BS; jj++).
{
C[i][jj] = (c [i][jj] + a[i][kk] * b[kk][jj]);
}
}
}
}
}
}
Esto se aplica a:
|