144 lines
5.3 KiB
C
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;
|
|
}
|