Correction de FIFO
This commit is contained in:
parent
964a5683fa
commit
996a76c7f5
@ -271,7 +271,6 @@ unsigned int recuperer_tag( unsigned int adresse, struct cache* c)
|
||||
return adresse>> bits_deplacer;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fonction : maj_info_fifo
|
||||
* Description : Cette fonction gère la politique de remplacement FIFO.
|
||||
@ -290,39 +289,19 @@ unsigned int recuperer_tag( unsigned int adresse, struct cache* c)
|
||||
* informations FIFO directement dans la structure de cache.
|
||||
*/
|
||||
void maj_info_fifo(unsigned int tag, unsigned int index, struct cache* c)
|
||||
{
|
||||
bool hit = false;
|
||||
{
|
||||
struct set *current_set = &c->sets[index];
|
||||
unsigned int pos_remplacement = current_set->fifo_head; // La position de remplacement est celle de la tête FIFO
|
||||
|
||||
// Vérifie si une ligne correspond au tag pour mettre à jour la FIFO
|
||||
for (unsigned int i = 0; i < c->associativite; i++)
|
||||
{
|
||||
if (c->sets[index].lines[i].valid && c->sets[index].lines[i].tag == tag)
|
||||
{
|
||||
// Hit trouvé, pas de remplacement nécessaire, on met juste à jour les infos
|
||||
c->sets[index].lines[i].fifo_position = c->sets[index].fifo_head; // Met à jour la position FIFO
|
||||
hit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Si c'est un miss, on remplace la ligne avec la plus ancienne (FIFO)
|
||||
if (!hit)
|
||||
{
|
||||
// Remplacement en FIFO : on remplace la ligne à la position "tail"
|
||||
c->sets[index].lines[c->sets[index].fifo_tail].valid = 1; // Marque la ligne comme valide
|
||||
c->sets[index].lines[c->sets[index].fifo_tail].tag = tag; // Met à jour le tag
|
||||
c->sets[index].lines[c->sets[index].fifo_tail].dirty = 0; // Réinitialise le bit dirty
|
||||
c->sets[index].lines[c->sets[index].fifo_tail].fifo_position = c->sets[index].fifo_head; // Met à jour la position FIFO
|
||||
|
||||
// Avancement de la queue FIFO pour la prochaine insertion/remplacement
|
||||
c->sets[index].fifo_tail = (c->sets[index].fifo_tail + 1) % c->associativite; // Le fifo_tail se déplace en circulaire
|
||||
}
|
||||
|
||||
// Incrémenter "fifo_head" à chaque nouvelle insertion pour suivre l'ordre FIFO
|
||||
c->sets[index].fifo_head = (c->sets[index].fifo_head + 1) % c->associativite; // Incrément circulaire également
|
||||
// Remplacer l'ancienne ligne par la nouvelle
|
||||
current_set->lines[pos_remplacement].tag = tag;
|
||||
current_set->lines[pos_remplacement].valid = 1; // Ligne maintenant valide
|
||||
current_set->lines[pos_remplacement].dirty = 0; // Par défaut, pas encore "salie"
|
||||
|
||||
// Mise à jour de la position FIFO (circular buffer)
|
||||
current_set->fifo_head = (current_set->fifo_head + 1) % c->associativite; // Avancer la tête
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fonction : calcul_hits_miss
|
||||
* Description : Cette fonction calcule les compteurs de hits et de misses pour une
|
||||
@ -339,111 +318,122 @@ void maj_info_fifo(unsigned int tag, unsigned int index, struct cache* c)
|
||||
* - void : La fonction ne retourne aucune valeur, mais met à jour les
|
||||
* compteurs et les informations de la mémoire cache directement.
|
||||
*/
|
||||
void calcul_hits_miss( struct reference_memoire m, struct cache* c)
|
||||
{
|
||||
// Récupère le tag et l'index de l'adresse mémoire
|
||||
unsigned int tag = recuperer_tag(m.adresse,c);
|
||||
unsigned int index = recuperer_index(m.adresse,c);
|
||||
unsigned int i = 0;
|
||||
void calcul_hits_miss(struct reference_memoire m, struct cache* c) {
|
||||
unsigned int index = recuperer_index(m.adresse, c);
|
||||
unsigned int tag = recuperer_tag(m.adresse, c);
|
||||
struct set* current_set = &c->sets[index];
|
||||
|
||||
// Mesurer les temps d'accés
|
||||
clock_t start_time = clock(); // Démarrer le chronomètre
|
||||
|
||||
// Vérifier si la référence entraîne un miss
|
||||
bool miss = true; // Initialement, on suppose qu'il y a un miss
|
||||
for (i=0;i<c->associativite;i++)
|
||||
{
|
||||
struct line temp = c->sets[index].lines[i];
|
||||
clock_t start_time = clock(); // Démarrer le chronomètre
|
||||
|
||||
// Vérifie si la ligne est valide et si le tag correspond
|
||||
if (temp.tag == tag && temp.valid)
|
||||
{
|
||||
miss = false; // Hit trouvé
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Charger la valeur dans la cache si c'est un miss
|
||||
if ( miss )
|
||||
{
|
||||
c->action.memory_accesses++; // Compte l'accès mémoire
|
||||
// Logique pour les accès en lecture
|
||||
if (m.adresse_type == 0) { // 0 pour lecture
|
||||
c->action.data_read_reference_count++;
|
||||
|
||||
// Gestion de la politique d'écriture pour Write Back
|
||||
if (c->write_policy==1 && c->sets[index].lines[0].dirty == 1) // Write Back et set dirty
|
||||
{
|
||||
c->action.memory_accesses++; // Incrémente l'accès mémoire
|
||||
c->sets[index].lines[0].dirty = 0; // Réinitialise le bit dirty
|
||||
}
|
||||
// Met à jour les lignes du set
|
||||
for(i=0;i<c->associativite;i++)
|
||||
{
|
||||
c->sets[index].lines[i].valid = 1; // Marque la ligne comme valide
|
||||
if (m.adresse_type == 1) c->sets[index].lines[i].dirty = 1; // Si c'est une écriture, marque dirty à 1
|
||||
c->sets[index].lines[i].tag = tag; // Met à jour le tag
|
||||
}
|
||||
// Vérification des hits
|
||||
for (unsigned int i = 0; i < c->associativite; i++) {
|
||||
if (current_set->lines[i].valid && current_set->lines[i].tag == tag) {
|
||||
// Hit
|
||||
c->action.data_read_hit_count++;
|
||||
// Fin de la mesure de temps
|
||||
clock_t end_time = clock(); // Arrêter le chronomètre
|
||||
double elapsed_time = ((double)(end_time - start_time)) / CLOCKS_PER_SEC; // Temps écoulé en secondes
|
||||
c->total_access_time += elapsed_time; // Ajouter au temps total d'accès
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Incrémente le compteur de miss selon le type d'adresse
|
||||
switch (m.adresse_type)
|
||||
{
|
||||
case 0:
|
||||
c->action.data_read_miss_count++;
|
||||
break;
|
||||
case 1:
|
||||
c->action.data_write_miss_count++;
|
||||
break;
|
||||
case 2:
|
||||
c->action.instruction_miss_count++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // C'est un hit et non pas un miss
|
||||
{
|
||||
// Incrémente le compteur de hit selon le type d'adresse
|
||||
switch (m.adresse_type)
|
||||
{
|
||||
case 0:
|
||||
c->action.data_read_hit_count++;
|
||||
break;
|
||||
case 1:
|
||||
c->action.data_write_hit_count++;
|
||||
break;
|
||||
case 2:
|
||||
c->action.instruction_hit_count++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Met à jour les informations FIFO pour le tag et l'index
|
||||
maj_info_fifo(tag,index,c);
|
||||
// Miss
|
||||
c->action.data_read_miss_count++;
|
||||
// Incrémenter le compteur total d'accès
|
||||
c->action.memory_accesses++;
|
||||
|
||||
// Fin de la mesure de temps
|
||||
// Gérer l'insertion dans la cache (FIFO)
|
||||
if (current_set->fifo_tail < c->associativite) {
|
||||
// Insérer dans une ligne vide
|
||||
current_set->lines[current_set->fifo_tail].valid = 1;
|
||||
current_set->lines[current_set->fifo_tail].tag = tag;
|
||||
current_set->fifo_tail++;
|
||||
} else {
|
||||
// Remplacer selon FIFO
|
||||
maj_info_fifo(tag, index, c); // Appel à la fonction de mise à jour
|
||||
}
|
||||
}
|
||||
// Logique pour les écritures
|
||||
else if (m.adresse_type == 1) { // 1 pour écriture
|
||||
c->action.data_write_reference_count++;
|
||||
|
||||
// Vérification des hits
|
||||
for (unsigned int i = 0; i < c->associativite; i++) {
|
||||
if (current_set->lines[i].valid && current_set->lines[i].tag == tag) {
|
||||
// Hit
|
||||
c->action.data_write_hit_count++;
|
||||
current_set->lines[i].dirty = 1; // Marquer comme "dirty"
|
||||
// Fin de la mesure de temps
|
||||
clock_t end_time = clock(); // Arrêter le chronomètre
|
||||
double elapsed_time = ((double)(end_time - start_time)) / CLOCKS_PER_SEC; // Temps écoulé en secondes
|
||||
c->total_access_time += elapsed_time; // Ajouter au temps total d'accès
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Miss
|
||||
c->action.data_write_miss_count++;
|
||||
// Incrémenter le compteur total d'accès
|
||||
c->action.memory_accesses++;
|
||||
|
||||
// Gérer l'insertion dans la cache (FIFO)
|
||||
if (current_set->fifo_tail < c->associativite) {
|
||||
// Insérer dans une ligne vide
|
||||
current_set->lines[current_set->fifo_tail].valid = 1;
|
||||
current_set->lines[current_set->fifo_tail].tag = tag;
|
||||
current_set->lines[current_set->fifo_tail].dirty = 1; // Marquer comme "dirty"
|
||||
current_set->fifo_tail++;
|
||||
} else {
|
||||
// Remplacer selon FIFO
|
||||
maj_info_fifo(tag, index, c); // Appel à la fonction de mise à jour
|
||||
}
|
||||
}
|
||||
// Logique pour les instructions
|
||||
else if (m.adresse_type == 2) { // 2 pour instruction
|
||||
c->action.instruction_reference_count++;
|
||||
|
||||
// Vérification des hits
|
||||
for (unsigned int i = 0; i < c->associativite; i++) {
|
||||
if (current_set->lines[i].valid && current_set->lines[i].tag == tag) {
|
||||
// Hit
|
||||
c->action.instruction_hit_count++;
|
||||
// Fin de la mesure de temps
|
||||
clock_t end_time = clock(); // Arrêter le chronomètre
|
||||
double elapsed_time = ((double)(end_time - start_time)) / CLOCKS_PER_SEC; // Temps écoulé en secondes
|
||||
c->total_access_time += elapsed_time; // Ajouter au temps total d'accès
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Miss
|
||||
c->action.instruction_miss_count++;
|
||||
// Incrémenter le compteur total d'accès
|
||||
c->action.memory_accesses++;
|
||||
|
||||
// Gérer l'insertion dans la cache (FIFO)
|
||||
if (current_set->fifo_tail < c->associativite) {
|
||||
// Insérer dans une ligne vide
|
||||
current_set->lines[current_set->fifo_tail].valid = 1;
|
||||
current_set->lines[current_set->fifo_tail].tag = tag;
|
||||
current_set->fifo_tail++;
|
||||
} else {
|
||||
// Remplacer selon FIFO
|
||||
maj_info_fifo(tag, index, c); // Appel à la fonction de mise à jour
|
||||
}
|
||||
}
|
||||
|
||||
// Fin de la mesure de temps pour les cas de misses
|
||||
clock_t end_time = clock(); // Arrêter le chronomètre
|
||||
double elapsed_time = ((double)(end_time - start_time)) / CLOCKS_PER_SEC; // Temps écoulé en secondes
|
||||
c->total_access_time += elapsed_time; // Ajouter au temps total d'accès
|
||||
|
||||
// Incrémente le compteur de références selon le type d'adresse
|
||||
switch (m.adresse_type)
|
||||
{
|
||||
case 0:
|
||||
c->action.data_read_reference_count++;
|
||||
break;
|
||||
case 1:
|
||||
c->action.data_write_reference_count++;
|
||||
break;
|
||||
case 2:
|
||||
c->action.instruction_reference_count++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fonction : get_hits_color
|
||||
* Description : Cette fonction détermine la couleur d'affichage basée sur le pourcentage
|
||||
@ -512,6 +502,7 @@ const char* get_misses_color(float percentage)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fonction : affiche_hits_miss
|
||||
* Description : Cette fonction affiche les statistiques de performance de la mémoire cache,
|
||||
@ -566,9 +557,10 @@ void affiche_hits_miss(struct cache * c)
|
||||
int miss_writes = c->action.data_write_miss_count;
|
||||
float pourcent_miss_reads = ((float)miss_reads / (float)accesses) * 100;
|
||||
float pourcent_miss_writes = ((float)miss_writes / (float)accesses) * 100;
|
||||
|
||||
|
||||
c->action.memory_accesses = c->action.memory_accesses * (c->taille_ligne / 4); // Convertit en nombre de mots
|
||||
|
||||
|
||||
// Afficher les hits et misses de manière formatée avec couleurs
|
||||
printf("%s----------------------------------------------------\n", COULEUR_BORDURE);
|
||||
printf("| %sStatistiques de Cache%s |\n", WHITE, COULEUR_BORDURE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user