Merge branch 'main' into fares
This commit is contained in:
commit
bad4cedf09
12 changed files with 493 additions and 164 deletions
6
Makefile
6
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)
|
||||
|
@ -45,8 +45,8 @@ all:
|
|||
threads: SCHED = sched-threads.o
|
||||
threads: release
|
||||
|
||||
stack: SCHED = sched-stack.o
|
||||
stack: release
|
||||
lifo: SCHED = sched-lifo.o
|
||||
lifo: release
|
||||
|
||||
random: SCHED = sched-random.o
|
||||
random: release
|
||||
|
|
22
README
22
README
|
@ -8,23 +8,29 @@ Compilation optimisée avec ordonnanceur *work-stealing*
|
|||
|
||||
Ce qui créer l'exécutable `ordonnanceur.elf`.
|
||||
|
||||
Paramètres disponibles :
|
||||
|
||||
Lancement utilisant tous les cœurs 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
|
||||
|
||||
./ordonnanceur.elf -t 0
|
||||
Exemple : quicksort en utilisant tous les cœurs disponibles
|
||||
|
||||
./ordonnanceur.elf -qt 0
|
||||
|
||||
|
||||
Autres options
|
||||
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 stack` : utilisation d'une pile
|
||||
- `make random` : idem que stack 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
|
||||
|
|
3
report/.gitignore
vendored
3
report/.gitignore
vendored
|
@ -6,3 +6,6 @@
|
|||
|
||||
!data
|
||||
!*.csv
|
||||
|
||||
!imgs
|
||||
!*.jpg
|
||||
|
|
103
report/data/machine1-mandelbrot.csv
Normal file
103
report/data/machine1-mandelbrot.csv
Normal file
|
@ -0,0 +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)
|
|
103
report/data/machine2-mandelbrot.csv
Normal file
103
report/data/machine2-mandelbrot.csv
Normal file
|
@ -0,0 +1,103 @@
|
|||
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)
|
|
103
report/data/machine2-quicksort.csv
Normal file
103
report/data/machine2-quicksort.csv
Normal file
|
@ -0,0 +1,103 @@
|
|||
serial;solution1;solution2;solution3;solution4
|
||||
1,169317;18,853278;0,351625;0,437063;0,382723
|
||||
1,135357;18,647222;0,346113;0,415457;0,381181
|
||||
1,116063;18,716067;0,333315;0,478798;0,398743
|
||||
1,114389;18,852186;0,405765;0,427855;0,416678
|
||||
1,100082;18,915434;0,345879;0,417337;0,377607
|
||||
1,122489;18,859351;0,341637;0,413364;0,378226
|
||||
1,118625;18,880979;0,338688;0,424781;0,371909
|
||||
1,116783;18,896289;0,340782;0,419739;0,376049
|
||||
1,123764;18,966756;0,34598;0,419586;0,378886
|
||||
1,112053;18,961847;0,347781;0,417307;0,371564
|
||||
1,106222;;0,345977;0,418911;0,382286
|
||||
1,117542;;0,344575;0,423238;0,374463
|
||||
1,123042;;0,380316;0,423481;0,384574
|
||||
1,122666;;0,348965;0,422239;0,386472
|
||||
1,094784;;0,350091;0,428141;0,413726
|
||||
1,117887;;0,347079;0,421924;0,379888
|
||||
1,107592;;0,351519;0,422242;0,379254
|
||||
1,110112;;0,348146;0,421897;0,383506
|
||||
1,110634;;0,344438;0,423664;0,375633
|
||||
1,122727;;0,352911;0,416374;0,379337
|
||||
1,118713;;0,358144;0,425869;0,378915
|
||||
1,145003;;0,357419;0,421071;0,383542
|
||||
1,158742;;0,352318;0,429645;0,380849
|
||||
1,139315;;0,351734;0,426712;0,378048
|
||||
1,11389;;0,348296;0,428159;0,3879
|
||||
1,115792;;0,344813;0,423699;0,377888
|
||||
1,130178;;0,35095;0,418282;0,370342
|
||||
1,13437;;0,37976;0,418731;0,385092
|
||||
1,118635;;0,370856;0,414341;0,384217
|
||||
1,130626;;0,352924;0,41674;0,373857
|
||||
1,131715;;0,344628;0,424953;0,385397
|
||||
1,126394;;0,350694;0,419971;0,377804
|
||||
1,119051;;0,357199;0,420048;0,380921
|
||||
1,166946;;0,357381;0,42662;0,377479
|
||||
1,131719;;0,349864;0,423074;0,378388
|
||||
1,122401;;0,356168;0,425048;0,383581
|
||||
1,153248;;0,354049;0,419466;0,385966
|
||||
1,137804;;0,345239;0,427234;0,384223
|
||||
1,154568;;0,344695;0,415409;0,3834
|
||||
1,134548;;0,351951;0,422346;0,377832
|
||||
1,141694;;0,346957;0,420225;0,383113
|
||||
1,138798;;0,349656;0,417503;0,374977
|
||||
1,14691;;0,354899;0,417815;0,380706
|
||||
1,156523;;0,353429;0,421822;0,383708
|
||||
1,156974;;0,356433;0,42952;0,380314
|
||||
1,137881;;0,350235;0,421268;0,37869
|
||||
1,182041;;0,341791;0,422629;0,389657
|
||||
1,255355;;0,355822;0,423966;0,373055
|
||||
1,274741;;0,352674;0,422633;0,364184
|
||||
1,286123;;0,351432;0,424711;0,411692
|
||||
1,316496;;0,344587;0,425153;0,419045
|
||||
1,264997;;0,355617;0,416388;0,429214
|
||||
1,294749;;0,351376;0,425924;0,412711
|
||||
1,279336;;0,356047;0,418391;0,416824
|
||||
1,15115;;0,353281;0,419928;0,414186
|
||||
1,157065;;0,352129;0,425628;0,415634
|
||||
1,134674;;0,342187;0,425554;0,411532
|
||||
1,148537;;0,352382;0,481699;0,407371
|
||||
1,162825;;0,354259;0,42336;0,421037
|
||||
1,125219;;0,355084;0,423364;0,417315
|
||||
1,135948;;0,351672;0,394221;0,412084
|
||||
1,126676;;0,355635;0,449527;0,4207
|
||||
1,138703;;0,349666;0,464888;0,423857
|
||||
1,119315;;0,351147;0,466629;0,409047
|
||||
1,148766;;0,347634;0,462687;0,418437
|
||||
1,141104;;0,341901;0,461755;0,415447
|
||||
1,118401;;0,343974;0,476791;0,417919
|
||||
1,128814;;0,348128;0,464594;0,419329
|
||||
1,121958;;0,34178;0,464364;0,414912
|
||||
1,128093;;0,345766;0,463223;0,414757
|
||||
1,128975;;0,347413;0,452773;0,405286
|
||||
1,121784;;0,359716;0,461508;0,423785
|
||||
1,132107;;0,352905;0,467514;0,391218
|
||||
1,133611;;0,355789;0,461167;0,415502
|
||||
1,130427;;0,346789;0,457815;0,412782
|
||||
1,126433;;0,356803;0,464759;0,420365
|
||||
1,123953;;0,348465;0,474755;0,410116
|
||||
1,127655;;0,354976;0,458914;0,410436
|
||||
1,132243;;0,352192;0,468238;0,40962
|
||||
1,143742;;0,348525;0,457865;0,410799
|
||||
1,106861;;0,351524;0,460753;0,420131
|
||||
1,120433;;0,348578;0,455885;0,412946
|
||||
1,135562;;0,343631;0,466659;0,417832
|
||||
1,117834;;0,350116;0,462351;0,409707
|
||||
1,11625;;0,333757;0,459712;0,405304
|
||||
1,11195;;0,341549;0,463326;0,406791
|
||||
1,127202;;0,373114;0,466854;0,41183
|
||||
1,101792;;0,379246;0,456734;0,413631
|
||||
1,120175;;0,38736;0,466337;0,414521
|
||||
1,111876;;0,384814;0,457412;0,411496
|
||||
1,118578;;0,380565;0,461057;0,40549
|
||||
1,12683;;0,386794;0,462855;0,419142
|
||||
1,138092;;0,377734;0,459669;0,414253
|
||||
1,116206;;0,38403;0,457826;0,42314
|
||||
1,104377;;0,384854;0,456568;0,413144
|
||||
1,117096;;0,394539;0,459206;0,411529
|
||||
1,099433;;0,419737;0,473687;0,408364
|
||||
1,133824;;0,425726;0,461766;0,409931
|
||||
1,131027;;0,417199;0,467319;0,40179
|
||||
1,138425;;0,386066;0,459411;0,413237
|
||||
;;;;
|
||||
=AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101)
|
|
|
@ -56,6 +56,9 @@
|
|||
\tableofcontents
|
||||
\clearpage
|
||||
|
||||
% TODO: Mandelbrot
|
||||
% TODO: Computer 2
|
||||
|
||||
\section{Descriptions}
|
||||
Description des différents algorithmes implémentés.
|
||||
|
||||
|
@ -108,8 +111,8 @@ fourni.
|
|||
\begin{description}
|
||||
\item[\mone] Le programme a été lancé \textbf{100 fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{0,855 secs}
|
||||
\item[\mtwo] Le programme a été lancé \textbf{\dots fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{\dots secs}
|
||||
\item[\mtwo] Le programme a été lancé \textbf{100 fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{1,139 secs}
|
||||
\end{description}
|
||||
|
||||
Ce programme ne bénéficie pas de toute la puissance de la machine.
|
||||
|
@ -118,8 +121,8 @@ Ce programme ne bénéficie pas de toute la puissance de la machine.
|
|||
\begin{description}
|
||||
\item[\mone] Le programme a été lancé \textbf{10 fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{35,985 secs}
|
||||
\item[\mtwo] Le programme a été lancé \textbf{\dots fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{\dots secs}
|
||||
\item[\mtwo] Le programme a été lancé \textbf{10 fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{18,854 secs}
|
||||
\end{description}
|
||||
|
||||
La création des threads pour chaque tâche créer un énorme
|
||||
|
@ -135,8 +138,8 @@ et donc il faut gérer les tâches et décider de quelle tâche va sur quel thre
|
|||
\begin{description}
|
||||
\item[\mone] Le programme a été lancé \textbf{100 fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{0,258 secs}
|
||||
\item[\mtwo] Le programme a été lancé \textbf{\dots fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{\dots secs}
|
||||
\item[\mtwo] Le programme a été lancé \textbf{100 fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{0,356 secs}
|
||||
\end{description}
|
||||
|
||||
Le lancement de nouveau thread étant limité, les performances
|
||||
|
@ -150,8 +153,8 @@ les performances sont aussi améliorées par rapport aux tests de
|
|||
\begin{description}
|
||||
\item[\mone] Le programme a été lancé \textbf{100 fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{0,390 secs}
|
||||
\item[\mtwo] Le programme a été lancé \textbf{\dots fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{\dots secs}
|
||||
\item[\mtwo] Le programme a été lancé \textbf{100 fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{0,438 secs}
|
||||
\end{description}
|
||||
|
||||
Cette implémentation est identique à \docref{stats:stack}, à l'exception que
|
||||
|
@ -164,11 +167,11 @@ Cette façon de faire réduit les performances.
|
|||
\begin{description}
|
||||
\item[\mone] Le programme a été lancé \textbf{100 fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{0,229 secs}
|
||||
\item[\mtwo] Le programme a été lancé \textbf{\dots fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{\dots secs}
|
||||
\item[\mtwo] Le programme a été lancé \textbf{100 fois}.
|
||||
Le temps moyen d'exécution a été de \textbf{0,397 secs}
|
||||
\end{description}
|
||||
|
||||
Dans cet implémentation, on n'utilises plus une pile mais un deck de tâches.
|
||||
Dans cet implémentation, on n'utilises plus une pile mais un deque de tâches.
|
||||
Cette façon de faire est légèrement meilleur que \docref{desc:th_pile}.
|
||||
|
||||
\end{document}
|
||||
|
|
BIN
report/imgs/mandelbrot.jpg
Normal file
BIN
report/imgs/mandelbrot.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
|
@ -11,7 +11,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)
|
||||
|
@ -103,10 +103,10 @@ 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);
|
||||
|
||||
|
@ -174,7 +174,9 @@ benchmark_mandelbrot(int serial, int nthreads)
|
|||
delay = end.tv_sec + end.tv_nsec / 1000000000.0 -
|
||||
(begin.tv_sec + begin.tv_nsec / 1000000000.0);
|
||||
|
||||
// Sauvegarde l'image pour voir si ça fonctionne correctement
|
||||
imageSaveBMP("mandelbrot.bmp", (unsigned char *)image, WIDTH, HEIGHT, 3, 8);
|
||||
|
||||
free(image);
|
||||
return delay;
|
||||
}
|
||||
|
|
258
src/sched-ws.c
258
src/sched-ws.c
|
@ -4,21 +4,37 @@
|
|||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Tâche */
|
||||
struct task_info {
|
||||
void *closure;
|
||||
taskfunc f;
|
||||
};
|
||||
|
||||
struct scheduler {
|
||||
/* Dernier élément du deck (premier ajouter) */
|
||||
int *bottom;
|
||||
/* Structure de chaque thread */
|
||||
struct worker {
|
||||
/* Premier élément du deque (dernier ajouter) */
|
||||
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;
|
||||
|
||||
/* Premier élément du deck (dernier 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.tasks = NULL;
|
||||
sched.threads = NULL;
|
||||
sched.top = NULL;
|
||||
sched.bottom = 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");
|
||||
sched.nthsleep = 0;
|
||||
|
||||
// Initialize workers
|
||||
if(!(sched.workers = malloc(nthreads * sizeof(struct worker)))) {
|
||||
perror("Workers");
|
||||
return -1;
|
||||
}
|
||||
for(int i = 0; i < nthreads; ++i) {
|
||||
sched.workers[i].bottom = 0;
|
||||
sched.workers[i].top = 0;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Initialisation du curseur suivant l'état de la pile de chaque processus
|
||||
if(!(sched.top = malloc(nthreads * sizeof(int)))) {
|
||||
perror("Cursor top stack");
|
||||
return sched_init_cleanup(sched, -1);
|
||||
}
|
||||
if(!(sched.bottom = malloc(nthreads * sizeof(int)))) {
|
||||
perror("Cursor bottom stack");
|
||||
return sched_init_cleanup(sched, -1);
|
||||
}
|
||||
for(int i = 0; i < nthreads; ++i) {
|
||||
sched.top[i] = 0;
|
||||
sched.bottom[i] = 0;
|
||||
}
|
||||
|
||||
// Allocation mémoire pour la pile de chaque processus
|
||||
if(!(sched.tasks = malloc(nthreads * sizeof(struct task_info *)))) {
|
||||
perror("Deck 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, "Deck for thread %d: %s\n", i, strerror(errno));
|
||||
// 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");
|
||||
// Création des threads
|
||||
for(int i = 0; i < nthreads; ++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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
sched.nthreads++;
|
||||
|
||||
pthread_mutex_unlock(&sched.mutex);
|
||||
}
|
||||
|
||||
// Ajoute la tâche initiale
|
||||
if(sched_spawn(f, closure, &sched) < 0) {
|
||||
fprintf(stderr, "Can't create the initial task\n");
|
||||
fprintf(stderr, "Can't queue the initial task\n");
|
||||
return sched_init_cleanup(sched, -1);
|
||||
}
|
||||
|
||||
// Démarre les threads
|
||||
// Attend la fin 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);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
return sched_init_cleanup(sched, -1);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&sched.mutex);
|
||||
sched.nthreads++;
|
||||
pthread_mutex_unlock(&sched.mutex);
|
||||
}
|
||||
|
||||
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.top) {
|
||||
free(s.top);
|
||||
s.top = NULL;
|
||||
}
|
||||
|
||||
if(s.bottom) {
|
||||
free(s.bottom);
|
||||
s.bottom = 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_lock(&s->mutex);
|
||||
|
||||
int next = (s->top[th] + 1) % s->qlen;
|
||||
if(next == s->bottom[th]) {
|
||||
pthread_mutex_unlock(&s->mutex);
|
||||
|
||||
pthread_mutex_lock(&s->workers[th].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->top[th]] = (struct task_info){closure, f};
|
||||
s->top[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,54 +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->bottom[curr_th] != s->top[curr_th]) {
|
||||
if(s->workers[curr_th].top != s->workers[curr_th].bottom) {
|
||||
found = 1;
|
||||
s->top[curr_th] = (s->top[curr_th] - 1 + s->qlen) % s->qlen;
|
||||
task = s->tasks[curr_th][s->top[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->bottom[target] != s->top[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->top[target] = (s->top[target] - 1 + s->qlen) % s->qlen;
|
||||
task = s->tasks[target][s->top[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);
|
||||
|
|
Reference in a new issue