#ifndef _ensemblevariables_hpp_ #define _ensemblevariables_hpp_ #include "functions.h" #include "Variable.hpp" #include #include #include #include using namespace std; class EnsembleVariables { int nb_vars; int nb_procs; int nb_diff_CL; int cache_lines; int line_size; int nb_lines_uncached; int tab_size_digits; Variable * LesVariables; void setnPubROWO(int n, int mode) { // mode = 0 : -> RO; mode = 1 : -> WO; mode = 2 -> Private // Les seules variables pouvant être mises en RO, en WO ou en private sont les variables publiques RW int nb_pub_rw = 0; for (int i = 0; i < nb_vars; i++) { if (LesVariables[i].getProc() == -1 && LesVariables[i].isRW()) { nb_pub_rw += 1; } } if (n > nb_pub_rw) { fprintf(stderr,"Error in function %s: cannot change attribute on as many variables\n",__func__); } int index; int index_to_set; for (int i = 0; i < n; i++) { index = randint(0,nb_pub_rw - 1); index_to_set = 0; for (int j = 0; j < index; j++) { index_to_set++; while (LesVariables[index_to_set].getProc() != -1 || !LesVariables[index_to_set].isRW()) { index_to_set++; } } if (mode == 0) { LesVariables[index_to_set].setRO(); } else if (mode == 1) { LesVariables[index_to_set].setWO(); } else { assert(mode == 2); int proc = randint(0,nb_procs - 1); LesVariables[index_to_set].setPrivate(proc); } nb_pub_rw--; } } public: EnsembleVariables(int nb_vars, int nb_procs, int nb_diff_CL, int cache_lines, int line_size, int nb_lines_uncached, int tab_size) { this->nb_vars = nb_vars; this->nb_procs = nb_procs; this->nb_diff_CL = nb_diff_CL; this->cache_lines = cache_lines; this->line_size = line_size; this->nb_lines_uncached = nb_lines_uncached; this->tab_size_digits = (int) ceil(log10(tab_size)); LesVariables = new Variable[nb_vars + nb_lines_uncached*line_size]; for (int i = nb_vars; i < nb_vars + nb_lines_uncached * line_size; i++) { LesVariables[i].setUncached(); LesVariables[i].setROorWO(); } } void setnPubRO(int n) { setnPubROWO(n, 0); } void setnPubWO(int n) { setnPubROWO(n, 1); } void setnPrivate(int n) { setnPubROWO(n, 2); } void setnPrivROWO(void) { // change les variables privées en RO ou WO, avec une probabilité de 20% pour chaque // Eventuellement changer l'interface en : changer strictement n variables privées en RO ou WO, comme pour le cas public for (int i = 0; i < nb_vars; i++) { if (LesVariables[i].getProc() != -1 && LesVariables[i].isRW()) { int r = randint(1,5); if (r == 1) { LesVariables[i].setRO(); } else if (r == 2) { LesVariables[i].setWO(); } } } } string writeVariablesNature() { assert(nb_vars % line_size == 0); stringstream res; res << "/*******************" << endl; res << "* Variables Nature *" << endl; res << "*******************/" << endl; for (int i = 0; i < (nb_vars / line_size) + nb_lines_uncached; i++) { if (i == 0) { res << "/*"; } else { res << " *"; } for (int j = 0; j < line_size; j++) { int var_index = i * line_size + j; int tab_index = index2realindex(var_index, nb_diff_CL, cache_lines, line_size); res << " [" << setw(tab_size_digits) << tab_index << "]"; if (LesVariables[var_index].isPublic()) { res << "Pub "; } else { res << setw(3) << LesVariables[var_index].getProc() << " "; } if (LesVariables[var_index].isRW()) { res << "RW "; } else if (LesVariables[var_index].isRO()) { res << "RO "; } else { assert(LesVariables[var_index].isWO()); res << "WO "; } if (LesVariables[var_index].isUnc()) { res << "(U)"; } else { res << " "; } } res << endl; } res << " */" << endl; return res.str(); } string writePrivateAccesses(int proc_id) { stringstream res; for (int i = 0; i < nb_vars; i++) { int tab_index = index2realindex(i, nb_diff_CL, cache_lines, line_size); if (LesVariables[i].isPrivate(proc_id)) { if (LesVariables[i].isRW()) { res << " tab[" << tab_index << "]++; // variable privee au proc " << proc_id << endl; } else if (LesVariables[i].isRO()) { res << " local_var = tab[" << tab_index << "]; // variable privee au proc " << proc_id << " et en RO" << endl; } else { assert(LesVariables[i].isWO()); res << " tab[" << tab_index << "] = 1; // variable privee au proc " << proc_id << " et en WO" << endl; } } } return res.str(); } int getVarCount(int proc_id) { // Retourne le nombre de variables pouvant être utilisées par le processeur proc_id int n = 0; for (int i = 0; i < nb_vars + nb_lines_uncached * line_size; i++) { if (LesVariables[i].isPublic() || LesVariables[i].isPrivate(proc_id)) { n++; } } return n; } bool isPublic(int var_index) { return LesVariables[var_index].isPublic(); } bool isRW(int var_index) { return LesVariables[var_index].isRW(); } bool isRO(int var_index) { return LesVariables[var_index].isRO(); } bool isWO(int var_index) { return LesVariables[var_index].isWO(); } bool isUnc(int var_index) { return LesVariables[var_index].isUnc(); } bool isPrivate(int var_index, int proc_id) { return LesVariables[var_index].isPrivate(proc_id); } }; #endif