From 083615bfd479202a5636b61bfc5ff8cdf3821dfc Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 24 Apr 2024 18:18:48 +0200 Subject: [PATCH 01/11] add m2m --- report/data/machine2-mandelbrot.csv | 206 ++++++++++++++-------------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/report/data/machine2-mandelbrot.csv b/report/data/machine2-mandelbrot.csv index f9a54d3..ce6ef24 100644 --- a/report/data/machine2-mandelbrot.csv +++ b/report/data/machine2-mandelbrot.csv @@ -1,103 +1,103 @@ -serial;solution1;solution2;solution3;solution4 -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -=AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101) +serial;solution1;solution2;solution3;solution4 +6,456785;7,686787;1,052787;1,035684;1,056697 +5,961551;7,456977;1,090401;1,078624;1,070915 +5,978221;7,492764;0,945853;0,940012;0,941003 +5,987699;7,487839;0,961475;0,930909;0,947027 +5,994593;7,475912;0,948906;0,93964;0,948985 +5,978152;7,501028;0,96521;0,945842;0,960884 +6,008653;7,492859;0,943485;0,938186;0,944773 +5,931275;7,508583;0,947526;0,936625;0,958647 +5,984718;7,48269;0,969535;0,941158;0,954904 +5,926464;7,521487;1,095308;0,962646;0,952086 +;;1,187541;1,120839;0,9507 +;;1,180552;1,117982;1,011738 +;;1,178994;1,101996;1,127789 +;;1,198735;1,115272;1,118482 +;;1,187537;1,114234;1,11758 +;;1,169716;1,122988;1,129877 +;;1,183357;1,116626;1,124217 +;;1,201513;1,11083;1,114629 +;;1,189228;1,112732;1,119815 +;;1,185339;1,191832;1,111635 +;;1,205089;1,1096;1,122624 +;;1,190949;1,102573;1,116943 +;;1,182796;1,104611;1,108262 +;;1,182168;1,110547;1,112515 +;;1,18521;1,120449;1,130948 +;;1,186162;1,107524;1,10815 +;;1,171052;1,104342;1,11375 +;;1,174987;1,115831;1,063593 +;;1,170191;1,115308;1,054527 +;;1,183476;1,117734;1,067821 +;;1,181003;1,098069;1,091237 +;;1,176937;1,099926;1,063959 +;;1,183003;1,104753;1,05376 +;;1,164995;1,129294;1,068562 +;;1,189621;1,103004;1,072569 +;;1,189487;1,101624;1,05788 +;;1,17728;1,107398;1,053151 +;;1,176664;1,107917;1,054929 +;;1,190181;1,106081;1,067136 +;;1,171804;1,110127;1,056735 +;;1,181075;1,103754;1,060074 +;;1,171117;1,105473;1,048996 +;;1,234976;1,111731;1,054774 +;;1,19734;1,100651;1,063619 +;;1,183142;1,106409;1,051499 +;;1,184678;1,102033;1,051034 +;;1,188219;1,111736;1,055196 +;;1,169105;1,101426;1,056565 +;;1,169737;1,102269;1,057922 +;;1,182779;1,102808;1,052283 +;;1,179676;1,103962;1,051546 +;;1,192515;1,114528;1,054307 +;;1,173776;1,104606;1,059195 +;;1,18694;1,111368;1,065876 +;;1,167176;1,10553;1,059063 +;;1,184172;1,121461;1,055983 +;;1,173655;1,101533;1,071379 +;;1,174559;1,109685;1,059781 +;;1,180622;1,105634;1,052543 +;;1,186669;1,102102;1,052587 +;;1,186964;1,110219;1,050079 +;;1,180694;1,108002;1,055051 +;;1,18293;1,112525;1,060719 +;;1,185275;1,105263;1,053945 +;;1,186219;1,114569;1,058368 +;;1,186204;1,10186;1,044708 +;;1,176664;1,103141;1,064363 +;;1,188062;1,101297;1,058389 +;;1,186302;1,107418;1,052813 +;;1,174208;1,109082;1,057208 +;;1,182153;1,103994;1,051057 +;;1,169753;1,099634;1,069187 +;;1,179525;1,10862;1,054363 +;;1,176094;1,118282;1,049696 +;;1,180424;1,109521;1,049554 +;;1,174649;1,111231;1,059195 +;;1,176279;1,109939;1,068946 +;;1,185085;1,105018;1,055443 +;;1,172958;1,119652;1,060145 +;;1,179878;1,102493;1,0528 +;;1,18904;1,103832;1,049931 +;;1,185939;1,10617;1,068577 +;;1,184071;1,110488;1,053296 +;;1,176863;1,10142;1,053043 +;;1,180537;1,10233;1,053079 +;;1,175333;1,110237;1,064754 +;;1,181432;1,102337;1,05552 +;;1,176338;1,124259;1,053189 +;;1,182357;1,160978;1,056288 +;;1,188036;1,107052;1,056224 +;;1,178734;1,107852;1,059644 +;;1,248277;1,109694;1,060426 +;;1,177892;1,106097;1,047429 +;;1,192703;1,104682;1,052129 +;;1,187199;1,105608;1,059152 +;;1,190741;1,10163;1,062313 +;;1,192773;1,110093;1,052282 +;;1,17697;1,107769;1,055542 +;;1,18526;1,109078;1,051843 +;;1,177081;1,103607;1,056059 +;;;; +=AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101) From 0d835b71702cf8c69490d0dd79ed756ce4f96c75 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 24 Apr 2024 18:27:44 +0200 Subject: [PATCH 02/11] add m1m --- report/data/machine1-mandelbrot.csv | 200 ++++++++++++++-------------- 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/report/data/machine1-mandelbrot.csv b/report/data/machine1-mandelbrot.csv index f9a54d3..e08f350 100644 --- a/report/data/machine1-mandelbrot.csv +++ b/report/data/machine1-mandelbrot.csv @@ -1,103 +1,103 @@ serial;solution1;solution2;solution3;solution4 -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; -;;;; +3,699373;5,488023;0,47237;0,478026;0,433025 +3,700028;5,455712;0,494962;0,43337;0,417979 +3,706003;5,525636;0,454447;0,4357;0,433579 +3,680465;5,782133;0,449261;0,448702;0,420426 +3,755356;5,760779;0,430482;0,432999;0,421888 +3,773443;5,628832;0,437057;0,451089;0,425781 +3,762929;5,534626;0,451706;0,442623;0,434668 +3,728524;5,547798;0,449807;0,435755;0,423926 +3,765843;5,544817;0,437969;0,428514;0,416397 +3,760712;5,559137;0,456097;0,459615;0,443395 +;;0,435231;0,447139;0,417403 +;;0,435863;0,431024;0,422645 +;;0,47099;0,442824;0,438633 +;;0,444217;0,426627;0,424975 +;;0,441064;0,428842;0,426369 +;;0,464321;0,455673;0,440124 +;;0,440808;0,431802;0,421606 +;;0,444501;0,431392;0,417215 +;;0,466562;0,451748;0,438959 +;;0,444408;0,440035;0,4254 +;;0,440298;0,429963;0,418044 +;;0,469805;0,445796;0,429213 +;;0,435337;0,428611;0,429957 +;;0,428776;0,430837;0,418727 +;;0,439373;0,445644;0,428272 +;;0,430075;0,439031;0,439621 +;;0,448776;0,431147;0,414435 +;;0,453934;0,452697;0,413957 +;;0,436708;0,43642;0,438138 +;;0,437682;0,439661;0,426635 +;;0,458744;0,448007;0,422047 +;;0,46211;0,439246;0,439724 +;;0,439103;0,436682;0,420238 +;;0,455765;0,443933;0,420346 +;;0,435958;0,443765;0,441586 +;;0,443098;0,43171;0,421882 +;;0,46374;0,465626;0,420092 +;;0,448221;0,434924;0,437275 +;;0,45311;0,427708;0,421062 +;;0,450469;0,427194;0,424122 +;;0,430775;0,433748;0,422986 +;;0,442299;0,420065;0,439952 +;;0,449738;0,426692;0,495084 +;;0,434351;0,437632;0,528238 +;;0,42759;0,431623;0,525092 +;;0,458849;0,42209;0,485978 +;;0,441104;0,438151;0,464852 +;;0,435596;0,422125;0,444847 +;;0,451678;0,413834;0,452927 +;;0,431298;0,449076;0,545694 +;;0,434293;0,418434;0,472326 +;;0,450405;0,425737;0,500946 +;;0,429664;0,435361;0,507181 +;;0,434408;0,428158;0,461463 +;;0,44453;0,429692;0,46309 +;;0,447389;0,428587;0,487651 +;;0,44155;0,433786;0,50062 +;;0,431118;0,423676;0,488046 +;;0,448942;0,426093;0,471528 +;;0,427483;0,44348;0,462296 +;;0,429674;0,420654;0,456372 +;;0,446553;0,422958;0,453673 +;;0,426328;0,436407;0,428236 +;;0,427325;0,422546;0,461682 +;;0,450518;0,426066;0,437946 +;;0,437274;0,439085;0,426752 +;;0,430804;0,417064;0,449537 +;;0,448709;0,422231;0,451591 +;;0,436712;0,437314;0,461608 +;;0,430153;0,426393;0,501439 +;;0,444711;0,421434;0,471776 +;;0,428339;0,430742;0,469594 +;;0,422936;0,430833;0,449374 +;;0,443323;0,419846;0,501901 +;;0,424732;0,434814;0,470192 +;;0,427097;0,442446;0,452176 +;;0,444068;0,456833;0,439405 +;;0,426348;0,438789;0,455701 +;;0,421448;0,437946;0,528443 +;;0,440158;0,430192;0,50939 +;;0,442971;0,42516;0,482255 +;;0,483969;0,456829;0,478885 +;;0,427999;0,431844;0,465756 +;;0,436225;0,435414;0,497307 +;;0,423702;0,444849;0,523557 +;;0,436075;0,420309;0,448597 +;;0,438504;0,424081;0,515072 +;;0,428824;0,439707;0,50559 +;;0,435219;0,418414;0,442364 +;;0,443414;0,425195;0,448883 +;;0,435936;0,432847;0,429692 +;;0,430754;0,426698;0,421615 +;;0,440062;0,420274;0,435846 +;;0,429719;0,440123;0,421792 +;;0,427208;0,426243;0,425134 +;;0,445394;0,419549;0,424762 +;;0,422881;0,421731;0,428183 +;;0,41912;0,433301;0,437734 +;;0,431884;0,420508;0,422997 +;;0,425924;0,423692;0,450753 ;;;; =AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101) From 3a7f8e70640c35cd4ee6f843dda984c260aacbe5 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 24 Apr 2024 18:31:02 +0200 Subject: [PATCH 03/11] fix warnings --- src/mandelbrot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mandelbrot.c b/src/mandelbrot.c index 6949e17..6040317 100644 --- a/src/mandelbrot.c +++ b/src/mandelbrot.c @@ -111,8 +111,8 @@ draw(void *closure, struct scheduler *s) if((end_x - start_x) < CHUNK_SIZE && (end_y - start_y) < CHUNK_SIZE) { // Si le morceau est petit alors on dessine - for(int y = start_y; y < end_y; y++) { - for(int x = start_x; x < end_x; x++) { + for(unsigned int y = start_y; y < end_y; y++) { + for(unsigned int x = start_x; x < end_x; x++) { pixel(image, x, y); } } From f3bc4d5abb2802b2ae440cbbcb5751aa3dab8f2d Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 24 Apr 2024 19:22:24 +0200 Subject: [PATCH 04/11] type issues --- src/mandelbrot.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mandelbrot.c b/src/mandelbrot.c index 6040317..9225dd1 100644 --- a/src/mandelbrot.c +++ b/src/mandelbrot.c @@ -102,17 +102,17 @@ draw(void *closure, struct scheduler *s) { struct mandelbrot_args *args = (struct mandelbrot_args *)closure; unsigned int *image = args->image; - unsigned int start_x = args->start_x; - unsigned int start_y = args->start_y; - unsigned int end_x = args->end_x; - unsigned int end_y = args->end_y; + int start_x = args->start_x; + int start_y = args->start_y; + int end_x = args->end_x; + int end_y = args->end_y; free(closure); if((end_x - start_x) < CHUNK_SIZE && (end_y - start_y) < CHUNK_SIZE) { // Si le morceau est petit alors on dessine - for(unsigned int y = start_y; y < end_y; y++) { - for(unsigned int x = start_x; x < end_x; x++) { + for(int y = start_y; y < end_y; y++) { + for(int x = start_x; x < end_x; x++) { pixel(image, x, y); } } From 4d47302cfcd6bb01e30fcc405f9294d96c6971b7 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 24 Apr 2024 22:23:53 +0200 Subject: [PATCH 05/11] use the tread sanitizer instead of the leak one --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3139b72..c891408 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ release: compilation debug: CFLAGS += -Wall -Wextra -Wshadow -Wcast-align -Wstrict-prototypes debug: CFLAGS += -fanalyzer -fsanitize=undefined -g -Og -debug: LDFLAGS += -fsanitize=undefined -fsanitize=leak +debug: LDFLAGS += -fsanitize=undefined -fsanitize=thread debug: compilation compilation: $(ALL_OBJECTS) From c0b12bfa504cd5379a7bab49477acace3dc39199 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 24 Apr 2024 22:29:32 +0200 Subject: [PATCH 06/11] reduce chunk size --- src/mandelbrot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mandelbrot.c b/src/mandelbrot.c index 9225dd1..489ed19 100644 --- a/src/mandelbrot.c +++ b/src/mandelbrot.c @@ -10,7 +10,7 @@ #define WIDTH 3840 #define HEIGHT 2160 #define ITERATIONS 1000 -#define CHUNK_SIZE 32 +#define CHUNK_SIZE 8 #define SCALE (WIDTH / 4.0) #define DX (WIDTH / 2) From f190c2f034c004b15b3edf51d3719d7ee6597180 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 24 Apr 2024 23:00:25 +0200 Subject: [PATCH 07/11] each structure now have his own mutex, finally taking advantage of the work stealing --- src/sched-ws.c | 247 +++++++++++++++++++++++++------------------------ 1 file changed, 126 insertions(+), 121 deletions(-) diff --git a/src/sched-ws.c b/src/sched-ws.c index bd300ca..759e41c 100644 --- a/src/sched-ws.c +++ b/src/sched-ws.c @@ -4,21 +4,37 @@ #include #include #include -#include +/* Tâche */ struct task_info { void *closure; taskfunc f; }; -struct scheduler { +/* Structure de chaque thread */ +struct worker { /* Premier élément du deque (dernier ajouter) */ - int *bottom; + int bottom; - /* Variable de conditions pour reveillé les threads au besoin */ + /* Mutex qui protège cette structure */ + pthread_mutex_t mutex; + + /* Deque de tâches */ + struct task_info *tasks; + + /* Thread */ + pthread_t thread; + + /* Dernier élément du deque (premier ajouter) */ + int top; +}; + +/* Scheduler partagé */ +struct scheduler { + /* Condition threads dormant */ pthread_cond_t cond; - /* Mutex qui protège les piles */ + /* Mutex qui protège cette structure */ pthread_mutex_t mutex; /* Nombre de threads instanciés */ @@ -27,17 +43,11 @@ struct scheduler { /* Compteur des threads dormants */ int nthsleep; - /* Taille des piles */ + /* Taille deque */ int qlen; - /* Piles de tâches */ - struct task_info **tasks; - - /* Liste des threads */ - pthread_t *threads; - - /* Dernier élément du deque (premier ajouter) */ - int *top; + /* Liste de workers par threads */ + struct worker *workers; }; /* Lance une tâche de la pile */ @@ -46,18 +56,16 @@ void *sched_worker(void *); /* Nettoie les opérations effectuées par l'initialisation de l'ordonnanceur */ int sched_init_cleanup(struct scheduler, int); -/* Récupère l'index du thread courant */ +/* Récupère l'index du thread courant + * + * Assume que le mutex de l'ordonnanceur est verrouillé */ int current_thread(struct scheduler *); int sched_init(int nthreads, int qlen, taskfunc f, void *closure) { static struct scheduler sched; - - sched.bottom = NULL; - sched.tasks = NULL; - sched.threads = NULL; - sched.top = NULL; + sched.workers = NULL; if(qlen <= 0) { fprintf(stderr, "qlen must be greater than 0\n"); @@ -73,7 +81,11 @@ sched_init(int nthreads, int qlen, taskfunc f, void *closure) } sched.nthreads = 0; - sched.nthsleep = 0; + // Initialisation variable de condition + if(pthread_cond_init(&sched.cond, NULL) != 0) { + fprintf(stderr, "Can't init condition variable\n"); + return sched_init_cleanup(sched, -1); + } // Initialisation du mutex if(pthread_mutex_init(&sched.mutex, NULL) != 0) { @@ -81,34 +93,28 @@ sched_init(int nthreads, int qlen, taskfunc f, void *closure) return sched_init_cleanup(sched, -1); } - // Initialisation variable de condition - if(pthread_cond_init(&sched.cond, NULL) != 0) { - fprintf(stderr, "Can't init varcond\n"); - return sched_init_cleanup(sched, -1); - } + sched.nthsleep = 0; - // Initialisation du curseur suivant l'état de la pile de chaque processus - if(!(sched.bottom = malloc(nthreads * sizeof(int)))) { - perror("Cursor bottom stack"); - return sched_init_cleanup(sched, -1); - } - if(!(sched.top = malloc(nthreads * sizeof(int)))) { - perror("Cursor top stack"); - return sched_init_cleanup(sched, -1); + // Initialize workers + if(!(sched.workers = malloc(nthreads * sizeof(struct worker)))) { + perror("Workers"); + return -1; } for(int i = 0; i < nthreads; ++i) { - sched.bottom[i] = 0; - sched.top[i] = 0; - } + sched.workers[i].bottom = 0; + sched.workers[i].top = 0; - // Allocation mémoire pour la pile de chaque processus - if(!(sched.tasks = malloc(nthreads * sizeof(struct task_info *)))) { - perror("Deque list"); - return sched_init_cleanup(sched, -1); - } - for(int i = 0; i < nthreads; ++i) { - if(!(sched.tasks[i] = malloc(qlen * sizeof(struct task_info)))) { - fprintf(stderr, "Deque for thread %d: %s\n", i, strerror(errno)); + // Initialisation mutex + if(pthread_mutex_init(&sched.workers[i].mutex, NULL) != 0) { + fprintf(stderr, "Can't init mutex %d\n", i); + return sched_init_cleanup(sched, -1); + } + + // Allocation mémoire deque + if(!(sched.workers[i].tasks = + malloc(sched.qlen * sizeof(struct task_info)))) { + fprintf(stderr, "Thread %d: ", i); + perror("Deque list"); return sched_init_cleanup(sched, -1); } } @@ -116,45 +122,44 @@ sched_init(int nthreads, int qlen, taskfunc f, void *closure) // Initialise l'aléatoire srand(time(NULL)); - // Créer les threads - if(!(sched.threads = malloc(nthreads * sizeof(pthread_t)))) { - perror("Threads"); - return sched_init_cleanup(sched, -1); - } - - // Ajoute la tâche initiale - if(sched_spawn(f, closure, &sched) < 0) { - fprintf(stderr, "Can't create the initial task\n"); - return sched_init_cleanup(sched, -1); - } - - // Démarre les threads + // Création des threads for(int i = 0; i < nthreads; ++i) { - if(pthread_create(&sched.threads[i], NULL, sched_worker, &sched) != 0) { - fprintf(stderr, "Can't create the thread %d\n", i); + pthread_mutex_lock(&sched.mutex); + if(pthread_create(&sched.workers[i].thread, NULL, sched_worker, + (void *)&sched) != 0) { + fprintf(stderr, "Can't create thread %d\n", i); - if(i > 0) { - fprintf(stderr, ", cancelling already created threads...\n"); - for(int j = 0; j < i; ++j) { - if(pthread_cancel(sched.threads[j]) != 0) { - fprintf(stderr, "Can't cancel the thread %d\n", j); - } - } - } else { - fprintf(stderr, "\n"); + // Annule les threads déjà créer + for(int j = 0; j < i; ++j) { + pthread_cancel(sched.workers[j].thread); } return sched_init_cleanup(sched, -1); } - pthread_mutex_lock(&sched.mutex); sched.nthreads++; + pthread_mutex_unlock(&sched.mutex); } + // Ajoute la tâche initiale + if(sched_spawn(f, closure, &sched) < 0) { + fprintf(stderr, "Can't queue the initial task\n"); + return sched_init_cleanup(sched, -1); + } + + // Attend la fin des threads for(int i = 0; i < nthreads; ++i) { - if((pthread_join(sched.threads[i], NULL) != 0)) { + if((pthread_join(sched.workers[i].thread, NULL) != 0)) { fprintf(stderr, "Can't wait the thread %d\n", i); + + // Quelque chose s'est mal passé, on annule les threads en cours + for(int j = 0; j < nthreads; ++j) { + if(j != i) { + pthread_cancel(sched.workers[j].thread); + } + } + return sched_init_cleanup(sched, -1); } } @@ -165,35 +170,20 @@ sched_init(int nthreads, int qlen, taskfunc f, void *closure) int sched_init_cleanup(struct scheduler s, int ret_code) { - pthread_mutex_destroy(&s.mutex); - pthread_cond_destroy(&s.cond); - if(s.tasks) { + pthread_mutex_destroy(&s.mutex); + + if(s.workers) { for(int i = 0; i < s.nthreads; ++i) { - if(s.tasks[i]) { - free(s.tasks[i]); - s.tasks[i] = NULL; - } + pthread_mutex_destroy(&s.workers[i].mutex); + + free(s.workers[i].tasks); + s.workers[i].tasks = NULL; } - free(s.tasks); - s.tasks = NULL; - } - - if(s.threads) { - free(s.threads); - s.threads = NULL; - } - - if(s.bottom) { - free(s.bottom); - s.bottom = NULL; - } - - if(s.top) { - free(s.top); - s.top = NULL; + free(s.workers); + s.workers = NULL; } return ret_code; @@ -204,14 +194,11 @@ current_thread(struct scheduler *s) { pthread_t current = pthread_self(); - pthread_mutex_lock(&s->mutex); for(int i = 0; i < s->nthreads; ++i) { - if(pthread_equal(s->threads[i], current)) { - pthread_mutex_unlock(&s->mutex); + if(pthread_equal(s->workers[i].thread, current)) { return i; } } - pthread_mutex_unlock(&s->mutex); return -1; } @@ -220,24 +207,28 @@ int sched_spawn(taskfunc f, void *closure, struct scheduler *s) { int th; + + pthread_mutex_lock(&s->mutex); if((th = current_thread(s)) < 0) { th = 0; } + pthread_mutex_unlock(&s->mutex); - pthread_mutex_lock(&s->mutex); + pthread_mutex_lock(&s->workers[th].mutex); - int next = (s->bottom[th] + 1) % s->qlen; - if(next == s->top[th]) { - pthread_mutex_unlock(&s->mutex); + int next = (s->workers[th].bottom + 1) % s->qlen; + if(next == s->workers[th].top) { + pthread_mutex_unlock(&s->workers[th].mutex); fprintf(stderr, "Stack is full\n"); errno = EAGAIN; return -1; } - s->tasks[th][s->bottom[th]] = (struct task_info){closure, f}; - s->bottom[th] = next; + s->workers[th].tasks[s->workers[th].bottom] = + (struct task_info){closure, f}; + s->workers[th].bottom = next; - pthread_mutex_unlock(&s->mutex); + pthread_mutex_unlock(&s->workers[th].mutex); return 0; } @@ -249,55 +240,69 @@ sched_worker(void *arg) // Récupère le processus courant (index tableau) int curr_th; + + pthread_mutex_lock(&s->mutex); while((curr_th = current_thread(s)) < 0); + pthread_mutex_unlock(&s->mutex); struct task_info task; int found; while(1) { found = 0; - pthread_mutex_lock(&s->mutex); + pthread_mutex_lock(&s->workers[curr_th].mutex); - if(s->top[curr_th] != s->bottom[curr_th]) { + if(s->workers[curr_th].top != s->workers[curr_th].bottom) { found = 1; - s->bottom[curr_th] = (s->bottom[curr_th] - 1 + s->qlen) % s->qlen; - task = s->tasks[curr_th][s->bottom[curr_th]]; + s->workers[curr_th].bottom = + (s->workers[curr_th].bottom - 1 + s->qlen) % s->qlen; + task = s->workers[curr_th].tasks[s->workers[curr_th].bottom]; } + pthread_mutex_unlock(&s->workers[curr_th].mutex); if(!found) { // Vol car aucune tâche trouvée - for(int i = 0, k = rand() % (s->nthreads + 1), target; - i < s->nthreads; ++i) { - target = (i + k) % s->nthreads; + pthread_mutex_lock(&s->mutex); + int nthreads = s->nthreads; + pthread_mutex_unlock(&s->mutex); - if(s->top[target] != s->bottom[target]) { + for(int i = 0, k = rand() % (nthreads + 1), target; i < nthreads; + ++i) { + target = (i + k) % nthreads; + + pthread_mutex_lock(&s->workers[target].mutex); + if(s->workers[target].top != s->workers[target].bottom) { // Tâche trouvée found = 1; - s->bottom[target] = - (s->bottom[target] - 1 + s->qlen) % s->qlen; - task = s->tasks[target][s->bottom[target]]; + s->workers[target].bottom = + (s->workers[target].bottom - 1 + s->qlen) % s->qlen; + task = s->workers[target].tasks[s->workers[target].bottom]; + + pthread_mutex_unlock(&s->workers[target].mutex); break; } + pthread_mutex_unlock(&s->workers[target].mutex); } // Aucune tâche à faire if(!found) { + pthread_mutex_lock(&s->mutex); s->nthsleep++; + // Ne partir que si tout le monde dort if(s->nthsleep >= s->nthreads) { pthread_cond_broadcast(&s->cond); pthread_mutex_unlock(&s->mutex); - break; } + pthread_cond_wait(&s->cond, &s->mutex); s->nthsleep--; + pthread_mutex_unlock(&s->mutex); continue; } } - - pthread_cond_broadcast(&s->cond); - pthread_mutex_unlock(&s->mutex); + pthread_cond_signal(&s->cond); // Exécute la tâche task.f(task.closure, s); From dbd4e5e499148a4aa9ee92bda31ccc60c0bc9c9e Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 24 Apr 2024 23:07:46 +0200 Subject: [PATCH 08/11] more readability --- README | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README b/README index d8ec5ee..68bc0c4 100644 --- a/README +++ b/README @@ -10,11 +10,11 @@ Ce qui créer l'exécutable `ordonnanceur.elf`. Paramètres disponibles : -- `-q` lance le benchmark avec quicksort -- `-m` lance le benchmark avec mandelbrot -- `-t n` où `n` est le nombre de threads à utiliser, 0 signifie qu'on utilise - tous les cœurs disponibles. -- `-s` n'utilises pas d'ordonnanceur +- `-q` : lance le benchmark avec quicksort +- `-m` : lance le benchmark avec mandelbrot +- `-t n` : où `n` est le nombre de threads à utiliser, 0 signifie qu'on utilise + tous les cœurs disponibles. +- `-s` : n'utilises pas d'ordonnanceur Exemple : quicksort en utilisant tous les cœurs disponibles From 1ebd0ab92a5b5e3201f0719bde8b9838fe906681 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 24 Apr 2024 23:08:26 +0200 Subject: [PATCH 09/11] even better --- README | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README b/README index 68bc0c4..acb3671 100644 --- a/README +++ b/README @@ -10,11 +10,11 @@ Ce qui créer l'exécutable `ordonnanceur.elf`. Paramètres disponibles : -- `-q` : lance le benchmark avec quicksort -- `-m` : lance le benchmark avec mandelbrot -- `-t n` : où `n` est le nombre de threads à utiliser, 0 signifie qu'on utilise - tous les cœurs disponibles. -- `-s` : n'utilises pas d'ordonnanceur +- -q : lance le benchmark avec quicksort +- -m : lance le benchmark avec mandelbrot +- -t n : où `n` est le nombre de threads à utiliser, 0 signifie qu'on utilise + tous les cœurs disponibles. +- -s : n'utilises pas d'ordonnanceur Exemple : quicksort en utilisant tous les cœurs disponibles From 72a719d115f4fc9e35b3e6eef5978ca25ec1bc2a Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 24 Apr 2024 23:08:47 +0200 Subject: [PATCH 10/11] final touch --- README | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README b/README index acb3671..31a90d1 100644 --- a/README +++ b/README @@ -10,11 +10,11 @@ Ce qui créer l'exécutable `ordonnanceur.elf`. Paramètres disponibles : -- -q : lance le benchmark avec quicksort -- -m : lance le benchmark avec mandelbrot -- -t n : où `n` est le nombre de threads à utiliser, 0 signifie qu'on utilise +* -q : lance le benchmark avec quicksort +* -m : lance le benchmark avec mandelbrot +* -t n : où `n` est le nombre de threads à utiliser, 0 signifie qu'on utilise tous les cœurs disponibles. -- -s : n'utilises pas d'ordonnanceur +* -s : n'utilises pas d'ordonnanceur Exemple : quicksort en utilisant tous les cœurs disponibles From fef0f0fb1a42144e58745d8e40d6502d06a7ffaa Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 24 Apr 2024 23:09:31 +0200 Subject: [PATCH 11/11] uniformization --- README | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README b/README index 31a90d1..6f860e9 100644 --- a/README +++ b/README @@ -27,10 +27,10 @@ Cible du makefile Il est possible d'utiliser d'autres implémentations d'ordonnanceur en changeant la cible du Makefile. -- `make threads` : lance juste des threads -- `make lifo` : utilisation d'une pile -- `make random` : idem que `lifo` mais en prenant une tâche aléatoire -- `make ws` : work-stealing +* `make threads` : lance juste des threads +* `make lifo` : utilisation d'une pile +* `make random` : idem que `lifo` mais en prenant une tâche aléatoire +* `make ws` : work-stealing Infos