AngoLinux

Ricerca della dimensione della cache

- A cura del Prof. Stefano Salvi -


Proviamo a individuare la dimensione della cache.

Il testo dell'esercizio è il seguente:

Scrivere un programma in C che valuti la dimensione della memoria cache installata nel sistema, facendo letture ripetute ad aree di memoria di dimensione crescente, da 512 Byte a 1MByte, raddoppiando ogni volta la diesnione dell'area.

NOTE:

  • Per misurare la durata di un evento si può utilizzare la funzione clock_t clock(void);, che ritorna una misura del tempo impiegato dal processo che lo richiama.
    Per ottenere una misura in secondi del tempo, occorre dividere il numero ottenuto da clock per la costante CLOCKS_PER_SEC.
    Per sapere la durata di una certa operazione, basta memorizzare il valore ritornato da clock prima di iniziare l'operazione e sottrarlo al valore ritornato dalla stessa funzione alla fine dell'operazione.
  • Perché la cache risponda corretamente, la memoria a cui si accede deve essere inizializzata con valori diversi, ad esempio, ogni elemento potrebbe essere inizializzato con il valore del suo indice.
  • Per semplificare la valutazione dei risultati, si può fare in modo che per ogni prova il numero di letture sia uguale. Ogni volta che si raddoppia la dimensione del vettore si può dimezzare il numero di prove. In questo modo, a parità di velocità della memoria, avremo tempi uguali. I tempi varieranno solo quando varierà la velocità della memoria (si passerà dalla cache alla RAM).

Una possibile soluzione è la seguente:
/* veloc_lett.c
 * Stefano Salvi - 20/10/2002
 * Programma che calcola la velocità di lettura*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define	MIN_DIM		512		/* dimensione minima (0,5K) */
#define	MAX_DIM		1048576		/* dimensione massima (1M) */
#define TOT_RD		(MAX_DIM*1024)	/* Numero totale di operazioni per test */

char *array(int dim); 			// funzione che alloca un array di dim byte
double lettura(char *vet,int dim,int v);// Legge 'v' volte l'array e ritorna i secondi impiegati

int main()
{
char *vet;		// Array del quale faro' eseguire le letture
int i;			// Dimensione crescente dell'array

  for(i=MIN_DIM; i<=MAX_DIM ;i*=2) 	// da 0,5 KB e 1 MB compresi
  {
    vet = array(i);			// Alloclo il vettore
    printf ("Array di %7d bytes: ",i);	// Messaggio di apertura
    /* Eseguo il test. Man mano che aumento la dimensione, riduco il numero di
     * ripetizioni, in modo che il prodotto non cambi. Cosi', a parita' di
     * velocita' della memoria, ho tempi uguali. */
    printf("%5.2f secondi\n",lettura(vet,i,TOT_RD/i));
    free (vet);				// dealloco il vettore
  }
  return 0;
}

/* Funzione che alloca un array di 'dim' caratteri e lo inizializza
 */
char *array(int dim) 			// funzione che alloca un array di dim byte
{
char *vet;				// Vettore da allocare

  vet = (char *)malloc(dim); 		// Alloco 'dim' byte di memoria
  while (dim--) vet [dim] = dim;	// Inizializzo gli elementi con il loro indice
  return vet; 				// Ritorno il array di char
}

/*funzione che legge un vettore per 'v' volte
 * Per minimizzare il tempo del ciclo, ogni volta leggo quattro elementi.
 * Ovviamente il vettore deve avere una dimensione multipla di 4.
 * 'vet' e' il vettore da leggere. 'dim' la sua dimensione.
 * Ritorna il tempo (in sec) impiegato per fare la lettura di memoria
 */
double lettura(char *vet,int dim,int v)
{
register int j;			// Indice dell'elemento da leggere
int i;				// Ripetizioni della lettura
register char c;		// Destinazione del dati letto
clock_t tIni;			// tempo iniziale
	
  tIni = clock();					// Misuro il tempo iniziale
  for(i = 0; i < v; i++)				// Ripeto per 'v' volte
  {
    j = dim;						// Inizializzazione indice
    do {
      c=vet[j--];					// Legge elemento 0
      c=vet[j--];					// Legge elemento 1
      c=vet[j--];					// Legge elemento 2
      c=vet[j--];					// Legge elemento 3
    } while (j>0);					// Limite ciclo
  }
  return (clock() - tIni)/(double)CLOCKS_PER_SEC;	// ritorna il tempo trascorso in secondi
}

Per provare il programma, scaricare il sorgente, compilarlo con il comando cc veloc_lett.c -o veloc_lett ed eseguirlo con il comando ./veloc_lett.


[Home Page dell'ITIS "Fermi"] [Indice Quarta] [Precedente] [Successivo]

© Ing. Stefano Salvi - Released under GPL licence