Correction de FIFO

This commit is contained in:
Moncef STITI 2024-10-10 19:35:10 +02:00
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);