2024-10-04 15:54:19 +02:00
/*
* Fichier : trace_generator . c
* Auteur : Moncef STITI
* Date : 04 / 11 / 2024
* Version : 1.1
* Description : Ce programme permet de générer des fichiers traces d ' accès en mémoire pour un projet de simulation de cache .
*/
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <time.h>
# define MAX_LINES 100000000
// Fonction pour générer une adresse mémoire aléatoire
unsigned int generer_adresse ( ) {
// Générer un nombre aléatoire pour l'adresse
// Utiliser un mélange de courtes et longues adresses
if ( rand ( ) % 2 = = 0 ) {
return rand ( ) % 0xFFFF ; // Adresse courte
} else {
return rand ( ) % 0xFFFFFFFF ; // Adresse longue
}
}
void generer_trace ( FILE * file , int total_lines , int read_data_lines , int write_data_lines , int read_instruction_lines ) {
int line_count = 0 ;
int type ;
unsigned int address ;
// Aléatoire pour les adresses
srand ( time ( NULL ) ) ;
// Continue jusqu'à ce que nous atteignons total_lines
while ( line_count < total_lines ) {
// Déterminer le type d'accès à faire
if ( read_data_lines > 0 & & ( rand ( ) % ( read_data_lines + write_data_lines + read_instruction_lines ) ) < read_data_lines ) {
type = 0 ; // Read data
address = generer_adresse ( ) ; // Adresse aléatoire
fprintf ( file , " %d %x \n " , type , address ) ;
read_data_lines - - ;
} else if ( write_data_lines > 0 & & ( rand ( ) % ( read_data_lines + write_data_lines + read_instruction_lines ) ) < ( read_data_lines + write_data_lines ) ) {
type = 1 ; // Write data
address = generer_adresse ( ) ; // Adresse aléatoire
fprintf ( file , " %d %x \n " , type , address ) ;
write_data_lines - - ;
} else if ( read_instruction_lines > 0 ) {
type = 2 ; // Read instruction
address = generer_adresse ( ) ; // Adresse aléatoire
fprintf ( file , " %d %x \n " , type , address ) ;
read_instruction_lines - - ;
} else {
// Si tous les types d'accès ont été utilisés, on arrête la génération
break ;
}
line_count + + ;
}
// Si nous avons moins de lignes que total_lines, complétons avec des lignes aléatoires
while ( line_count < total_lines ) {
type = rand ( ) % 3 ; // Choisir un type aléatoire
address = generer_adresse ( ) ; // Adresse aléatoire
fprintf ( file , " %d %x \n " , type , address ) ;
line_count + + ;
}
}
void afficher_usage ( ) {
printf ( " Utilisation : trace_generator -l <total_lines> [-r <read_data_lines>] [-w <write_data_lines>] [-i <read_instruction_lines>] -o <output_file> \n " ) ;
printf ( " -l <total_lines> Nombre total de lignes dans le fichier de trace \n " ) ;
printf ( " -r <read_data_lines> Nombre de lignes de données lues (type 0) [optionnel] \n " ) ;
printf ( " -w <write_data_lines> Nombre de lignes de données écrites (type 1) [optionnel] \n " ) ;
printf ( " -i <read_instruction_lines> Nombre de lignes d'instructions lues (type 2) [optionnel] \n " ) ;
printf ( " -o <output_file> Nom du fichier de sortie \n " ) ;
}
int main ( int argc , char * argv [ ] ) {
int total_lines = 0 ;
int read_data_lines = 0 ;
int write_data_lines = 0 ;
int read_instruction_lines = 0 ;
char * output_file = NULL ;
int opt ;
while ( ( opt = getopt ( argc , argv , " l:r:w:i:o: " ) ) ! = - 1 ) {
switch ( opt ) {
case ' l ' :
total_lines = atoi ( optarg ) ;
break ;
case ' r ' :
read_data_lines = atoi ( optarg ) ;
break ;
case ' w ' :
write_data_lines = atoi ( optarg ) ;
break ;
case ' i ' :
read_instruction_lines = atoi ( optarg ) ;
break ;
case ' o ' :
output_file = optarg ;
break ;
default :
afficher_usage ( ) ;
return EXIT_FAILURE ;
}
}
// Vérification de la validité des arguments
if ( total_lines < = 0 | | output_file = = NULL ) {
afficher_usage ( ) ;
return EXIT_FAILURE ;
}
// Vérification que le nombre total de lignes demandées est correct
int total_requested_lines = read_data_lines + write_data_lines + read_instruction_lines ;
if ( total_requested_lines > total_lines ) {
fprintf ( stderr , " Erreur : La somme des lignes de données lues (%d), écrites (%d) et d'instructions lues (%d) dépasse le nombre total de lignes (%d). \n " ,
read_data_lines , write_data_lines , read_instruction_lines , total_lines ) ;
return EXIT_FAILURE ;
}
// Si aucun type de ligne n'est précisé, générons une distribution par défaut
if ( total_requested_lines = = 0 ) {
// Exemple de distribution : 50% de lectures, 30% d'écritures, 20% d'instructions
read_data_lines = total_lines * 0.5 ;
write_data_lines = total_lines * 0.3 ;
read_instruction_lines = total_lines * 0.2 ;
}
FILE * file = fopen ( output_file , " w " ) ;
if ( file = = NULL ) {
perror ( " Erreur : Impossible d'ouvrir le fichier d'output. " ) ;
return EXIT_FAILURE ;
}
generer_trace ( file , total_lines , read_data_lines , write_data_lines , read_instruction_lines ) ;
fclose ( file ) ;
printf ( " Le fichier trace '%s' avec %d lignes a été généré avec succès. \n " , output_file , total_lines ) ;
return EXIT_SUCCESS ;
2024-10-07 20:37:16 +02:00
}