144 lines
5.3 KiB
C

/*
* 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;
}