From 2b63897e057df06441ae79570752f5c4791f1c54 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 00:09:01 +0200 Subject: [PATCH 01/35] new mandelbrot results --- 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 e08f350..7a1cda0 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 +3,699373;69,908451;0,748724;0,724536;0,4388 +3,700028;69,651509;0,758207;0,735602;0,452657 +3,706003;70,409085;0,760916;0,77577;0,471077 +3,680465;68,879508;0,754408;0,856882;0,463803 +3,755356;68,715224;0,758946;0,735604;0,436798 +3,773443;70,05263;0,742368;0,715597;0,485953 +3,762929;61,071574;0,757395;0,709591;0,449706 +3,728524;61,826388;0,76639;0,709813;0,432972 +3,765843;60,281954;0,755399;0,724667;0,443676 +3,760712;59,989333;0,760786;0,731358;0,482156 +;;0,753061;0,751812;0,486163 +;;0,732515;0,737792;0,463441 +;;0,766985;0,727256;0,461299 +;;0,755468;0,758367;0,452605 +;;0,754449;0,743946;0,463087 +;;0,763504;0,737184;0,508087 +;;0,816164;0,718047;0,443023 +;;0,818466;0,707516;0,466842 +;;0,820094;0,714751;0,427232 +;;0,777806;0,72513;0,454773 +;;0,756754;0,736922;0,481304 +;;0,756295;0,726482;0,457485 +;;0,764344;0,725604;0,435368 +;;0,812846;0,703642;0,454735 +;;0,794532;0,701544;0,439924 +;;0,802799;0,714291;0,432497 +;;0,776952;0,701825;0,456261 +;;0,811182;0,731952;0,435513 +;;0,867716;0,725562;0,434193 +;;0,786163;0,744599;0,438291 +;;0,817451;0,744788;0,45231 +;;0,814847;0,705125;0,456504 +;;0,775259;0,715851;0,428383 +;;0,873499;0,726173;0,470819 +;;0,833682;0,714716;0,485135 +;;0,788488;0,71715;0,464806 +;;0,803513;0,72059;0,448136 +;;0,765686;0,736539;0,471816 +;;0,764588;0,715728;0,441337 +;;0,780008;0,724693;0,427149 +;;0,759503;0,711983;0,448329 +;;0,769281;0,70784;0,461468 +;;0,759218;0,741248;0,438958 +;;0,762445;0,697456;0,447645 +;;0,766437;0,710466;0,44675 +;;0,762647;0,71167;0,448525 +;;0,760154;0,705879;0,415549 +;;0,762126;0,724284;0,448755 +;;0,772651;0,70883;0,446395 +;;0,770516;0,709702;0,47213 +;;0,765692;0,723043;0,422993 +;;0,776426;0,704135;0,41982 +;;0,75852;0,701932;0,451463 +;;0,757897;0,72304;0,479726 +;;0,752233;0,705475;0,465615 +;;0,762813;0,706186;0,470113 +;;0,774626;0,742427;0,448547 +;;0,76221;0,704019;0,436901 +;;0,770988;0,710307;0,457316 +;;0,773389;0,740255;0,41779 +;;0,765078;0,707632;0,41624 +;;0,75806;0,70628;0,439199 +;;0,840276;0,711741;0,444 +;;0,809256;0,718686;0,435362 +;;0,831878;0,706377;0,424162 +;;0,818649;0,747162;0,46451 +;;0,82472;0,703069;0,458657 +;;0,821336;0,712093;0,451079 +;;0,774274;0,721804;0,444846 +;;0,816145;0,713959;0,404737 +;;0,833468;0,725223;0,444446 +;;0,84426;0,721485;0,441903 +;;0,814416;0,717384;0,439355 +;;0,806517;0,728766;0,446225 +;;0,774625;0,71279;0,447389 +;;0,799289;0,709757;0,401106 +;;0,790709;0,731097;0,431719 +;;0,823297;0,722108;0,420039 +;;0,814804;0,708578;0,439513 +;;0,842211;0,732622;0,426168 +;;0,86405;0,715635;0,440741 +;;0,820204;0,711505;0,443982 +;;0,815872;0,732674;0,481752 +;;0,809534;0,713409;0,47172 +;;0,826922;0,715205;0,43914 +;;0,806153;0,716027;0,510146 +;;0,87398;0,706652;0,414881 +;;0,801666;0,729932;0,436974 +;;0,796379;0,719451;0,418621 +;;0,77153;0,709199;0,418687 +;;0,761019;0,728372;0,424339 +;;0,776813;0,703809;0,441159 +;;0,797319;0,705532;0,450558 +;;0,766324;0,731904;0,457835 +;;0,809568;0,709436;0,462539 +;;0,794211;0,718473;0,444126 +;;0,779595;0,71933;0,416904 +;;0,777302;0,707086;0,422294 +;;0,786113;0,721242;0,45898 +;;0,779815;0,718811;0,419718 ;;;; =AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101) From f88f6cf0543ac3f653720817606cea705e143437 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 00:20:41 +0200 Subject: [PATCH 02/35] update machine2 data --- report/data/machine2-mandelbrot.csv | 200 ++++++++++++++-------------- report/data/machine2-quicksort.csv | 200 ++++++++++++++-------------- 2 files changed, 200 insertions(+), 200 deletions(-) diff --git a/report/data/machine2-mandelbrot.csv b/report/data/machine2-mandelbrot.csv index ce6ef24..0f98b18 100644 --- a/report/data/machine2-mandelbrot.csv +++ b/report/data/machine2-mandelbrot.csv @@ -1,103 +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 +6,456785;41,649159;1,961234;1,75471;0,858611 +5,961551;41,159579;1,867443;1,889605;0,894257 +5,978221;40,853888;1,850687;1,9106;0,852761 +5,987699;41,108181;1,844775;1,889086;0,889301 +5,994593;41,039507;1,859437;1,870542;0,894762 +5,978152;40,552478;1,846758;1,892396;0,898126 +6,008653;40,871344;1,846668;1,887571;0,905322 +5,931275;40,921027;1,856589;1,882765;0,929054 +5,984718;41,185944;1,850752;1,887107;0,906014 +5,926464;41,262677;1,871987;1,865323;0,910078 +;;1,83989;1,916642;0,923592 +;;1,852396;1,89344;0,95798 +;;1,862238;1,866349;1,154997 +;;1,858035;1,883279;1,181362 +;;1,846289;1,894672;1,168078 +;;1,843845;1,886991;1,170702 +;;1,851448;1,867351;1,17776 +;;1,839527;1,874013;1,169461 +;;1,846443;1,897992;1,153499 +;;1,841239;1,812167;1,166388 +;;1,861473;1,885996;1,150545 +;;1,832398;1,869662;1,149051 +;;1,854925;1,854097;1,158301 +;;1,876801;1,882358;1,186379 +;;1,84395;1,861017;1,148933 +;;1,861973;1,871175;1,621548 +;;1,853741;1,863857;1,188869 +;;1,832475;1,867693;1,172454 +;;1,864345;1,863113;1,166068 +;;1,853464;1,866527;1,180661 +;;1,85081;1,885281;1,167348 +;;1,889002;1,875104;1,186249 +;;1,860324;1,871488;1,39919 +;;1,854712;1,874508;1,179918 +;;1,855974;1,873498;1,177229 +;;1,851012;1,877581;1,174236 +;;1,865635;1,868135;1,17737 +;;1,853532;1,868136;1,158592 +;;1,854242;1,853068;1,245401 +;;1,870519;1,873454;1,145411 +;;1,845472;1,863465;1,137178 +;;1,838413;1,856358;1,13146 +;;1,857152;1,875315;1,1778 +;;1,857796;1,846695;1,194727 +;;1,867392;1,914703;1,165279 +;;1,844359;1,867281;1,157697 +;;1,851905;1,840478;1,170331 +;;1,864936;1,884241;1,14201 +;;1,851607;1,860397;1,137485 +;;1,867725;1,893906;1,159054 +;;1,851121;1,874498;1,172483 +;;1,862048;1,889899;1,161742 +;;1,885169;1,868436;1,152555 +;;1,873032;1,906535;1,145294 +;;1,856007;1,88278;1,14767 +;;1,857178;1,882084;1,137471 +;;1,847874;1,874691;1,15807 +;;1,845905;1,906517;1,173693 +;;1,871005;1,866356;1,244258 +;;1,854912;1,875587;1,126782 +;;1,873241;1,889467;1,13651 +;;1,846162;1,892907;1,141141 +;;1,845868;1,844845;1,152296 +;;1,868418;1,885305;1,149503 +;;1,868781;1,857484;1,129044 +;;1,866335;1,894812;1,136199 +;;1,896873;1,862369;1,156769 +;;1,846406;1,874016;1,131681 +;;1,868205;1,88935;1,159828 +;;1,851202;1,870441;1,189857 +;;1,856573;1,874161;1,123324 +;;1,857687;1,901919;1,131326 +;;1,846702;1,887909;1,158933 +;;1,844168;1,927572;1,127763 +;;1,873514;1,885122;1,147745 +;;1,868296;1,902559;1,156985 +;;1,869302;1,959778;1,139736 +;;1,856765;1,896785;1,15666 +;;1,940473;1,859601;1,141663 +;;1,882615;1,895935;1,145446 +;;1,853098;1,87943;1,162117 +;;1,851497;1,867225;1,127709 +;;1,857364;1,900579;1,089162 +;;1,857159;1,871569;1,121629 +;;1,869184;1,913335;1,132436 +;;1,849316;1,861857;1,172125 +;;1,83884;1,916172;1,166059 +;;1,855392;1,973927;1,128083 +;;1,85446;1,954403;1,116037 +;;1,864228;2,023192;1,153666 +;;1,862845;1,896327;1,146614 +;;1,840648;1,892307;1,142001 +;;1,857235;1,882943;1,141889 +;;1,861538;1,91871;1,164709 +;;1,844699;1,892722;1,141951 +;;1,873747;1,913999;1,101117 +;;1,849665;1,923279;1,158205 +;;1,855647;2,02672;1,118689 +;;1,876364;2,004184;1,093833 +;;1,855262;2,000091;1,120682 ;;;; =AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101) diff --git a/report/data/machine2-quicksort.csv b/report/data/machine2-quicksort.csv index 71045df..04f7c7e 100644 --- a/report/data/machine2-quicksort.csv +++ b/report/data/machine2-quicksort.csv @@ -1,103 +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 +1,169317;18,853278;0,351625;0,437063;0,277223 +1,135357;18,647222;0,346113;0,415457;0,30976 +1,116063;18,716067;0,333315;0,478798;0,29798 +1,114389;18,852186;0,405765;0,427855;0,296451 +1,100082;18,915434;0,345879;0,417337;0,27663 +1,122489;18,859351;0,341637;0,413364;0,289742 +1,118625;18,880979;0,338688;0,424781;0,276373 +1,116783;18,896289;0,340782;0,419739;0,298701 +1,123764;18,966756;0,34598;0,419586;0,280514 +1,112053;18,961847;0,347781;0,417307;0,282288 +1,106222;;0,345977;0,418911;0,29461 +1,117542;;0,344575;0,423238;0,283487 +1,123042;;0,380316;0,423481;0,303554 +1,122666;;0,348965;0,422239;0,277983 +1,094784;;0,350091;0,428141;0,302062 +1,117887;;0,347079;0,421924;0,279742 +1,107592;;0,351519;0,422242;0,296745 +1,110112;;0,348146;0,421897;0,281091 +1,110634;;0,344438;0,423664;0,30145 +1,122727;;0,352911;0,416374;0,28529 +1,118713;;0,358144;0,425869;0,301081 +1,145003;;0,357419;0,421071;0,277248 +1,158742;;0,352318;0,429645;0,309069 +1,139315;;0,351734;0,426712;0,28449 +1,11389;;0,348296;0,428159;0,300195 +1,115792;;0,344813;0,423699;0,280263 +1,130178;;0,35095;0,418282;0,293245 +1,13437;;0,37976;0,418731;0,277778 +1,118635;;0,370856;0,414341;0,284453 +1,130626;;0,352924;0,41674;0,284434 +1,131715;;0,344628;0,424953;0,280787 +1,126394;;0,350694;0,419971;0,282349 +1,119051;;0,357199;0,420048;0,270621 +1,166946;;0,357381;0,42662;0,324383 +1,131719;;0,349864;0,423074;0,309926 +1,122401;;0,356168;0,425048;0,318613 +1,153248;;0,354049;0,419466;0,312714 +1,137804;;0,345239;0,427234;0,31447 +1,154568;;0,344695;0,415409;0,357493 +1,134548;;0,351951;0,422346;0,304176 +1,141694;;0,346957;0,420225;0,319239 +1,138798;;0,349656;0,417503;0,314283 +1,14691;;0,354899;0,417815;0,308839 +1,156523;;0,353429;0,421822;0,322845 +1,156974;;0,356433;0,42952;0,307459 +1,137881;;0,350235;0,421268;0,311346 +1,182041;;0,341791;0,422629;0,424512 +1,255355;;0,355822;0,423966;0,295332 +1,274741;;0,352674;0,422633;0,317655 +1,286123;;0,351432;0,424711;0,30888 +1,316496;;0,344587;0,425153;0,365595 +1,264997;;0,355617;0,416388;0,317795 +1,294749;;0,351376;0,425924;0,30476 +1,279336;;0,356047;0,418391;0,324489 +1,15115;;0,353281;0,419928;0,302113 +1,157065;;0,352129;0,425628;0,320394 +1,134674;;0,342187;0,425554;0,313931 +1,148537;;0,352382;0,481699;0,313504 +1,162825;;0,354259;0,42336;0,327433 +1,125219;;0,355084;0,423364;0,303773 +1,135948;;0,351672;0,394221;0,319334 +1,126676;;0,355635;0,449527;0,306527 +1,138703;;0,349666;0,464888;0,335988 +1,119315;;0,351147;0,466629;0,312778 +1,148766;;0,347634;0,462687;0,306124 +1,141104;;0,341901;0,461755;0,325993 +1,118401;;0,343974;0,476791;0,306907 +1,128814;;0,348128;0,464594;0,316588 +1,121958;;0,34178;0,464364;0,304631 +1,128093;;0,345766;0,463223;0,317844 +1,128975;;0,347413;0,452773;0,327408 +1,121784;;0,359716;0,461508;0,312561 +1,132107;;0,352905;0,467514;0,346329 +1,133611;;0,355789;0,461167;0,307356 +1,130427;;0,346789;0,457815;0,31519 +1,126433;;0,356803;0,464759;0,322447 +1,123953;;0,348465;0,474755;0,313538 +1,127655;;0,354976;0,458914;0,401558 +1,132243;;0,352192;0,468238;0,307872 +1,143742;;0,348525;0,457865;0,304387 +1,106861;;0,351524;0,460753;0,318627 +1,120433;;0,348578;0,455885;0,308049 +1,135562;;0,343631;0,466659;0,316858 +1,117834;;0,350116;0,462351;0,308032 +1,11625;;0,333757;0,459712;0,328463 +1,11195;;0,341549;0,463326;0,319812 +1,127202;;0,373114;0,466854;0,305431 +1,101792;;0,379246;0,456734;0,322798 +1,120175;;0,38736;0,466337;0,304799 +1,111876;;0,384814;0,457412;0,316439 +1,118578;;0,380565;0,461057;0,308321 +1,12683;;0,386794;0,462855;0,315443 +1,138092;;0,377734;0,459669;0,315014 +1,116206;;0,38403;0,457826;0,316235 +1,104377;;0,384854;0,456568;0,323074 +1,117096;;0,394539;0,459206;0,305813 +1,099433;;0,419737;0,473687;0,321035 +1,133824;;0,425726;0,461766;0,302243 +1,131027;;0,417199;0,467319;0,312465 +1,138425;;0,386066;0,459411;0,321559 ;;;; =AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101) From f277b9ea4cc8f3f21641f7317ba67b14c3771cdc Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 00:39:13 +0200 Subject: [PATCH 03/35] Add stats --- src/sched-ws.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/sched-ws.c b/src/sched-ws.c index 759e41c..c57877f 100644 --- a/src/sched-ws.c +++ b/src/sched-ws.c @@ -11,11 +11,26 @@ struct task_info { taskfunc f; }; +/* Statistiques */ +struct stats { + /* Total des vols échoués */ + int total_failed_steal; + + /* Total des vols */ + int total_steal; + + /* Total des tâches effecutés */ + int total_tasks; +}; + /* Structure de chaque thread */ struct worker { /* Premier élément du deque (dernier ajouter) */ int bottom; + /* Statistiques récoltés */ + struct stats data; + /* Mutex qui protège cette structure */ pthread_mutex_t mutex; @@ -101,8 +116,10 @@ sched_init(int nthreads, int qlen, taskfunc f, void *closure) return -1; } for(int i = 0; i < nthreads; ++i) { - sched.workers[i].bottom = 0; - sched.workers[i].top = 0; + // Statistiques + sched.workers[i].data.total_failed_steal = 0; + sched.workers[i].data.total_steal = 0; + sched.workers[i].data.total_tasks = 0; // Initialisation mutex if(pthread_mutex_init(&sched.workers[i].mutex, NULL) != 0) { @@ -110,13 +127,15 @@ sched_init(int nthreads, int qlen, taskfunc f, void *closure) return sched_init_cleanup(sched, -1); } - // Allocation mémoire deque + // Initialisation 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); } + sched.workers[i].bottom = 0; + sched.workers[i].top = 0; } // Initialise l'aléatoire @@ -164,6 +183,25 @@ sched_init(int nthreads, int qlen, taskfunc f, void *closure) } } + /* Statistiques */ + + int total_failed_steal = 0; + int total_steal = 0; + int total_tasks = 0; + + for(int i = 0; i < sched.nthreads; ++i) { + total_failed_steal += sched.workers[i].data.total_failed_steal; + total_steal += sched.workers[i].data.total_steal; + total_tasks += sched.workers[i].data.total_tasks; + } + + printf("------- Statistiques -------\n"); + printf(" Total tâches\t : %d\n", total_tasks); + printf(" Total vols\t : %d\n", total_steal); + printf(" Total vols réussis : %d\n", total_steal - total_failed_steal); + printf(" Total vols échoués : %d\n", total_failed_steal); + printf("----------------------------\n"); + return sched_init_cleanup(sched, 1); } @@ -224,6 +262,8 @@ sched_spawn(taskfunc f, void *closure, struct scheduler *s) return -1; } + s->workers[th].data.total_tasks++; + s->workers[th].tasks[s->workers[th].bottom] = (struct task_info){closure, f}; s->workers[th].bottom = next; @@ -261,6 +301,8 @@ sched_worker(void *arg) if(!found) { // Vol car aucune tâche trouvée + s->workers[curr_th].data.total_steal++; + pthread_mutex_lock(&s->mutex); int nthreads = s->nthreads; pthread_mutex_unlock(&s->mutex); @@ -285,6 +327,8 @@ sched_worker(void *arg) // Aucune tâche à faire if(!found) { + s->workers[curr_th].data.total_failed_steal++; + pthread_mutex_lock(&s->mutex); s->nthsleep++; From 2e69f11b38f9c6594559b3ce4c74b33c78b43068 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 00:51:25 +0200 Subject: [PATCH 04/35] add btm pictures --- report/imgs/bottom-lifo.jpg | Bin 0 -> 40368 bytes report/imgs/bottom-ws.jpg | Bin 0 -> 39331 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 report/imgs/bottom-lifo.jpg create mode 100644 report/imgs/bottom-ws.jpg diff --git a/report/imgs/bottom-lifo.jpg b/report/imgs/bottom-lifo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2eac15e58d548dea38d2cb9fbb7c7c93e4b4eea9 GIT binary patch literal 40368 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

er&p4Ow>ZF3vD;^+YM78C3&OLRb_yPj) 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 literal 0 HcmV?d00001 diff --git a/report/imgs/bottom-ws.jpg b/report/imgs/bottom-ws.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b520652565335b0bd74dbd3401c6fc48bc7d07ad GIT binary patch literal 39331 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 literal 0 HcmV?d00001 From b82c3b3605c22a5fefb11731314b8496857b5270 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 02:13:56 +0200 Subject: [PATCH 05/35] add mandelbrot --- report/document.tex | 130 ++++++++++++++++++++++++++++++++------------ 1 file changed, 95 insertions(+), 35 deletions(-) diff --git a/report/document.tex b/report/document.tex index c25a169..648abb0 100644 --- a/report/document.tex +++ b/report/document.tex @@ -62,7 +62,7 @@ \section{Descriptions} Description des différents algorithmes implémentés. -\subsection{Naïf} +\subsection{Séquentiel} Cette implémentation naïve correspond au mode \texttt{serial} de \texttt{quicksort.c}. Elle lance les tâches sans threads. @@ -85,44 +85,71 @@ aléatoire de la pile. \subsection{Répartition par work-stealing} \begin{itemize} - \item Au lieu d'avoir une pile unique, chaque thread à sa propre liste - \item Chaque tâche est ajouté sur le même thread de sa création. - \item Quand un thread n'as pas de tâches à faire, il vole une tâche à un autre - thread, en partant de la fin + \item Au lieu d'avoir une pile unique, chaque thread à sa propre liste + \item Chaque tâche est ajouté sur le même thread de sa création. + \item Quand un thread n'as pas de tâches à faire, il vole une tâche à un autre + thread, en partant de la fin \end{itemize} \section{Statistiques} -Chaque implémentation a été testée avec l'optimisation de niveau 2 -de \texttt{gcc}, sur 2 machines. - -Le programme utilisé pour tester les implémentations est le \texttt{quicksort} -fourni. - \def\mone{\textit{Machine 1}} % fixe \def\mtwo{\textit{Machine 2}} % portable +\def\bone{\textit{Benchmark quicksort}} +\def\btwo{\textit{Benchmark mandelbrot}} + +Chaque implémentation a été testée avec l'optimisation de niveau 2 +de \texttt{gcc}, sur 2 machines. + \begin{enumerate} - \item \textbf{12 \coeurs} pour la \mone. - \item \textbf{8 \coeurs} pour la \mtwo. + \item \textbf{12 \coeurs} pour la \mone. + \item \textbf{8 \coeurs} pour la \mtwo. \end{enumerate} -\subsection{Naïf}\label{stats:naive} +Le programme utilisé pour tester les implémentations sont le quicksort fourni +et une adaptation de mandelbrot fournis dans le TP10. + +\subsection{Séquentiel}\label{stats:seq} \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{100 fois}. - Le temps moyen d'exécution a été de \textbf{1,139 secs} + \item[\bone] \hspace{1em} + \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{100 fois}. + Le temps moyen d'exécution a été de \textbf{1,139 secs} + \end{description} + + \item[\btwo] \hspace{1em} + \begin{description} + \item[\mone] Le programme a été lancé \textbf{10 fois}. + Le temps moyen d'exécution a été de \textbf{3,733 secs} + \item[\mtwo] Le programme a été lancé \textbf{10 fois}. + Le temps moyen d'exécution a été de \textbf{6,020 secs} + \end{description} \end{description} + Ce programme ne bénéficie pas de toute la puissance de la machine. \subsection{Threads sans gestion}\label{stats:th_ges} + \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{10 fois}. - Le temps moyen d'exécution a été de \textbf{18,854 secs} + \item[\bone] \hspace{1em} + \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{10 fois}. + Le temps moyen d'exécution a été de \textbf{18,854 secs} + \end{description} + + \item[\btwo] \hspace{1em} + \begin{description} + \item[\mone] Le programme a été lancé \textbf{10 fois}. + Le temps moyen d'exécution a été de \textbf{66,078 secs} + \item[\mtwo] Le programme a été lancé \textbf{10 fois}. + Le temps moyen d'exécution a été de \textbf{41,060 secs} + \end{description} \end{description} La création des threads pour chaque tâche créer un énorme @@ -136,10 +163,21 @@ et donc il faut gérer les tâches et décider de quelle tâche va sur quel thre \subsection{Threads avec pile}\label{stats:stack} \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{100 fois}. - Le temps moyen d'exécution a été de \textbf{0,356 secs} + \item[\bone] \hspace{1em} + \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{100 fois}. + Le temps moyen d'exécution a été de \textbf{0,356 secs} + \end{description} + + \item[\btwo] \hspace{1em} + \begin{description} + \item[\mone] Le programme a été lancé \textbf{100 fois}. + Le temps moyen d'exécution a été de \textbf{0,787 secs} + \item[\mtwo] Le programme a été lancé \textbf{100 fois}. + Le temps moyen d'exécution a été de \textbf{1,858 secs} + \end{description} \end{description} Le lancement de nouveau thread étant limité, les performances @@ -147,14 +185,25 @@ sont grandement améliorées par rapport aux tests de \docref{stats:th_ges}. Également grâce au fait que désormais on utilise les \coeurs~de notre CPU, les performances sont aussi améliorées par rapport aux tests de -\docref{stats:naive}. +\docref{stats:seq}. \subsubsection{Sélection aléatoire de tâche} \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{100 fois}. - Le temps moyen d'exécution a été de \textbf{0,438 secs} + \item[\bone] \hspace{1em} + \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{100 fois}. + Le temps moyen d'exécution a été de \textbf{0,438 secs} + \end{description} + + \item[\btwo] \hspace{1em} + \begin{description} + \item[\mone] Le programme a été lancé \textbf{100 fois}. + Le temps moyen d'exécution a été de \textbf{0,438 secs} + \item[\mtwo] Le programme a été lancé \textbf{100 fois}. + Le temps moyen d'exécution a été de \textbf{1,887 secs} + \end{description} \end{description} Cette implémentation est identique à \docref{stats:stack}, à l'exception que @@ -165,10 +214,21 @@ Cette façon de faire réduit les performances. \subsection{Répartition par work-stealing} \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{100 fois}. - Le temps moyen d'exécution a été de \textbf{0,397 secs} + \item[\bone] \hspace{1em} + \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{100 fois}. + Le temps moyen d'exécution a été de \textbf{0,308 secs} + \end{description} + + \item[\btwo] \hspace{1em} + \begin{description} + \item[\mone] Le programme a été lancé \textbf{100 fois}. + Le temps moyen d'exécution a été de \textbf{0,447 secs} + \item[\mtwo] Le programme a été lancé \textbf{100 fois}. + Le temps moyen d'exécution a été de \textbf{1,131 secs} + \end{description} \end{description} Dans cet implémentation, on n'utilises plus une pile mais un deque de tâches. From 0850ce8b90cd433960d35cad6502f8000a3294c4 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 02:43:13 +0200 Subject: [PATCH 06/35] images en vrac --- report/document.tex | 53 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/report/document.tex b/report/document.tex index 648abb0..6f0b3e4 100644 --- a/report/document.tex +++ b/report/document.tex @@ -24,6 +24,9 @@ \setminted[c]{autogobble,frame=lines} \usemintedstyle{emacs} +% Images +\usepackage{graphicx} + \def\titleName{Projet : Un ordonnanceur par work stealing} \def\docTitle{\href{https://www.irif.fr/~jch/enseignement/systeme/projet.pdf}{\titleName}} @@ -48,7 +51,10 @@ % Aliases \def\coeurs{c\oe{}urs} - +\def\mone{\textit{Machine 1}} % fixe +\def\mtwo{\textit{Machine 2}} % portable +\def\bone{\textit{Benchmark quicksort}} +\def\btwo{\textit{Benchmark mandelbrot}} \begin{document} \maketitle @@ -56,9 +62,6 @@ \tableofcontents \clearpage -% TODO: Mandelbrot -% TODO: Computer 2 - \section{Descriptions} Description des différents algorithmes implémentés. @@ -83,7 +86,8 @@ Même fonctionnement que dans l'algorithme de \docref{desc:th_pile}, sauf qu'au lieu de récupérer la dernière tâche, on récupère une tâche aléatoire de la pile. -\subsection{Répartition par work-stealing} +\subsection{Répartition par work-stealing}\label{desc:ws} +% TODO: Faire des phrases \begin{itemize} \item Au lieu d'avoir une pile unique, chaque thread à sa propre liste \item Chaque tâche est ajouté sur le même thread de sa création. @@ -91,14 +95,14 @@ aléatoire de la pile. thread, en partant de la fin \end{itemize} +\section{Comportement} +% TODO +% Expliquer comportement LIFO vs WS +% Expliquer comportement dans le code +% Expliquer ce qu'il se passe quand on modifie le nombre de threads + \section{Statistiques} -\def\mone{\textit{Machine 1}} % fixe -\def\mtwo{\textit{Machine 2}} % portable - -\def\bone{\textit{Benchmark quicksort}} -\def\btwo{\textit{Benchmark mandelbrot}} - Chaque implémentation a été testée avec l'optimisation de niveau 2 de \texttt{gcc}, sur 2 machines. @@ -187,6 +191,13 @@ sont grandement améliorées par rapport aux tests de \docref{stats:th_ges}. les performances sont aussi améliorées par rapport aux tests de \docref{stats:seq}. +% TODO: parler de l'image +\begin{figure}[h!] + \centering + \includegraphics[width=\textwidth]{imgs/bottom-lifo.jpg} + \caption{Utilisation ressources sur la \mone~avec \docref{desc:th_pile}} +\end{figure} + \subsubsection{Sélection aléatoire de tâche} \begin{description} \item[\bone] \hspace{1em} @@ -234,4 +245,24 @@ Cette façon de faire réduit les performances. 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}. +% TODO: parler de l'image +\begin{figure}[h!] + \centering + \includegraphics[width=\textwidth]{imgs/bottom-ws.jpg} + \caption{Exploitation des ressources sur la \mone~avec \docref{desc:ws}} +\end{figure} + +\clearpage +\appendix + +% TODO +% Images à insérer +% Mettre un lien vers Fares + mentionner que j'ai testé via sa fonction bmp + +\begin{figure}[h!] + \centering + \includegraphics[width=0.7\textwidth]{imgs/mandelbrot.jpg} + \caption{Example de Mandelbrot} +\end{figure} + \end{document} From 561116ee032aaf9b16868e51720cd13343218b2b Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 02:53:29 +0200 Subject: [PATCH 07/35] Add alt text --- report/document.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/report/document.tex b/report/document.tex index 6f0b3e4..1d75dc9 100644 --- a/report/document.tex +++ b/report/document.tex @@ -194,7 +194,7 @@ les performances sont aussi améliorées par rapport aux tests de % TODO: parler de l'image \begin{figure}[h!] \centering - \includegraphics[width=\textwidth]{imgs/bottom-lifo.jpg} + \includegraphics[alt={Graphique},width=\textwidth]{imgs/bottom-lifo.jpg} \caption{Utilisation ressources sur la \mone~avec \docref{desc:th_pile}} \end{figure} @@ -248,7 +248,7 @@ Cette façon de faire est légèrement meilleur que \docref{desc:th_pile}. % TODO: parler de l'image \begin{figure}[h!] \centering - \includegraphics[width=\textwidth]{imgs/bottom-ws.jpg} + \includegraphics[alt={Graphique},width=\textwidth]{imgs/bottom-ws.jpg} \caption{Exploitation des ressources sur la \mone~avec \docref{desc:ws}} \end{figure} @@ -261,7 +261,7 @@ Cette façon de faire est légèrement meilleur que \docref{desc:th_pile}. \begin{figure}[h!] \centering - \includegraphics[width=0.7\textwidth]{imgs/mandelbrot.jpg} + \includegraphics[alt={Fractale mandelbrot},width=0.7\textwidth]{imgs/mandelbrot.jpg} \caption{Example de Mandelbrot} \end{figure} From 526bc15ec8391666fbfe80fabb99bcc3ec1f5125 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 12:04:31 +0200 Subject: [PATCH 08/35] support fast web view --- report/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/report/Makefile b/report/Makefile index 3f37dcc..5ea438e 100644 --- a/report/Makefile +++ b/report/Makefile @@ -5,11 +5,13 @@ SRC = $(TEX) PDF = $(TEX:.tex=.pdf) TEXMK = latexmk -shell-escape -lualatex -interaction=nonstopmode +QPDF = qpdf --linearize --replace-input all: $(PDF) $(PDF): %.pdf: %.tex $(TEXMK) $< + @$(QPDF) $@ 2>/dev/null |: EXTS = aux fdb_latexmk fls log nav out snm synctex.gz toc clean: From b2c0879f90a25c28574b8ae289f923ac9b829ab3 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 12:50:35 +0200 Subject: [PATCH 09/35] fix todos, small fixes, a4 paper, french quotes --- report/document.tex | 81 ++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/report/document.tex b/report/document.tex index 1d75dc9..b5d559c 100644 --- a/report/document.tex +++ b/report/document.tex @@ -1,13 +1,9 @@ \DocumentMetadata{testphase = {phase-II,sec,toc,graphic,minipage,float,text}} -\documentclass{article} +\documentclass[a4paper]{article} \usepackage[T1]{fontenc} % encoding \renewcommand{\familydefault}{\sfdefault} % sans-serif font -% Langages -\usepackage[french]{babel} -\frenchsetup{SmallCapsFigTabCaptions=false} - % Add \extra info to title \makeatletter \providecommand{\extra}[1]{ @@ -24,6 +20,12 @@ \setminted[c]{autogobble,frame=lines} \usemintedstyle{emacs} +% Langages +\usepackage[french]{babel} +\frenchsetup{SmallCapsFigTabCaptions=false} +\usepackage{csquotes} +\MakeOuterQuote{"} + % Images \usepackage{graphicx} @@ -50,11 +52,12 @@ \newcommand{\docref}[1]{\textit{\nameref{#1}}} % italic nameref % Aliases -\def\coeurs{c\oe{}urs} +\def\coeur{c\oe{}ur} \def\mone{\textit{Machine 1}} % fixe \def\mtwo{\textit{Machine 2}} % portable \def\bone{\textit{Benchmark quicksort}} \def\btwo{\textit{Benchmark mandelbrot}} +\def\ws{\enquote{work-stealing}} \begin{document} \maketitle @@ -86,20 +89,34 @@ Même fonctionnement que dans l'algorithme de \docref{desc:th_pile}, sauf qu'au lieu de récupérer la dernière tâche, on récupère une tâche aléatoire de la pile. -\subsection{Répartition par work-stealing}\label{desc:ws} -% TODO: Faire des phrases -\begin{itemize} - \item Au lieu d'avoir une pile unique, chaque thread à sa propre liste - \item Chaque tâche est ajouté sur le même thread de sa création. - \item Quand un thread n'as pas de tâches à faire, il vole une tâche à un autre - thread, en partant de la fin -\end{itemize} +\subsection{Répartition par \ws}\label{desc:ws} +Ici, chaque \coeur~a sa propre liste de tâche. Quand un thread n'as +plus de tâche, il essaie d'en voler une à un autre thread. + \section{Comportement} -% TODO -% Expliquer comportement LIFO vs WS -% Expliquer comportement dans le code -% Expliquer ce qu'il se passe quand on modifie le nombre de threads + +\subsection{Listes} +Dans l'ordonnanceur LIFO, la liste est une pile. Chaque thread récupère le +premier élément de la pile, c'est-à-dire le dernier à avoir été ajouté. + +Avec la répartition par \ws, la liste est une deque. Comme dans l'ordonnanceur +LIFO, chaque thread récupère le premier élément de la deque, mais quand il y a +un vol, c'est le dernier élément qui est récupéré par le thread. + +\subsection{Synchronisations} +Dans mes implémentations, j'ai exclusivement utilisé des mutex ainsi que des +variables de conditions pour endormir/réveiller mes threads. + +\subsection{Nombre de threads} +Pour avoir un programme performant, il faut équilibrer le nombre de threads par +rapport aux nombres de \coeur{}s disponibles. Il faut également équilibrer la +création de nouvelles tâches par thread par rapport au véritable travail +effectué par ledit thread. Par exemple dans le \btwo, chaque tâche soit créer 4 +nouvelles tâches, soit calcule une portion de l'image. Une plus grande création +de tâche favorise le \ws~parce qu'une pile unique atteint ses limites quand +trop de tâches est ajouté, car les threads n'ont pas le temps "d'abattre +le travail" assez rapidement. \section{Statistiques} @@ -107,8 +124,8 @@ Chaque implémentation a été testée avec l'optimisation de niveau 2 de \texttt{gcc}, sur 2 machines. \begin{enumerate} - \item \textbf{12 \coeurs} pour la \mone. - \item \textbf{8 \coeurs} pour la \mtwo. + \item \textbf{12 \coeur{}s} pour la \mone. + \item \textbf{8 \coeur{}s} pour la \mtwo. \end{enumerate} Le programme utilisé pour tester les implémentations sont le quicksort fourni @@ -187,15 +204,19 @@ et donc il faut gérer les tâches et décider de quelle tâche va sur quel thre Le lancement de nouveau thread étant limité, les performances sont grandement améliorées par rapport aux tests de \docref{stats:th_ges}. -Également grâce au fait que désormais on utilise les \coeurs~de notre CPU, +Également grâce au fait que désormais on utilise les \coeur{}s~de notre CPU, les performances sont aussi améliorées par rapport aux tests de \docref{stats:seq}. -% TODO: parler de l'image +Dans la \autoref{fig:btm-lifo}, on observe que les \coeur{}s du CPU ne sont pas +tous utilisé à 100\%. Ceci est dû au fait que l'accès à la liste des tâches est +limité, car partagé entres les threads. + \begin{figure}[h!] \centering \includegraphics[alt={Graphique},width=\textwidth]{imgs/bottom-lifo.jpg} \caption{Utilisation ressources sur la \mone~avec \docref{desc:th_pile}} + \label{fig:btm-lifo} \end{figure} \subsubsection{Sélection aléatoire de tâche} @@ -223,7 +244,7 @@ ajouté. Cette façon de faire réduit les performances. -\subsection{Répartition par work-stealing} +\subsection{Répartition par \ws} \begin{description} \item[\bone] \hspace{1em} \begin{description} @@ -245,24 +266,30 @@ Cette façon de faire réduit les performances. 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}. -% TODO: parler de l'image +Dans la \autoref{fig:btm-ws}, on observe que les \coeur{}s du CPU sont +proche de 100\% d'utilisation. Comparé à \docref{stats:stack}, on gagne +en moyenne \approx~10\% de l'utilisation du processeur dans son entièreté. + \begin{figure}[h!] \centering \includegraphics[alt={Graphique},width=\textwidth]{imgs/bottom-ws.jpg} \caption{Exploitation des ressources sur la \mone~avec \docref{desc:ws}} + \label{fig:btm-ws} \end{figure} \clearpage \appendix +\section{Crédits} -% TODO -% Images à insérer -% Mettre un lien vers Fares + mentionner que j'ai testé via sa fonction bmp +J'ai utilisé un bout de code de \href{https://expreg.org/amsi/C/}{Farès Belhadj} +d'un TP de L2 pour afficher une image au format \texttt{bmp} afin vérifier que +le \btwo~fonctionnait correctement. Ce qui donne la \autoref{fig:mandelbrot}. \begin{figure}[h!] \centering \includegraphics[alt={Fractale mandelbrot},width=0.7\textwidth]{imgs/mandelbrot.jpg} \caption{Example de Mandelbrot} + \label{fig:mandelbrot} \end{figure} \end{document} From aa51c8b049e0b4e257f64cba758580c056c22259 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 13:04:04 +0200 Subject: [PATCH 10/35] ugly fix for an unknown bug --- report/document.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/report/document.tex b/report/document.tex index b5d559c..113c0a7 100644 --- a/report/document.tex +++ b/report/document.tex @@ -283,7 +283,8 @@ en moyenne \approx~10\% de l'utilisation du processeur dans son entièreté. J'ai utilisé un bout de code de \href{https://expreg.org/amsi/C/}{Farès Belhadj} d'un TP de L2 pour afficher une image au format \texttt{bmp} afin vérifier que -le \btwo~fonctionnait correctement. Ce qui donne la \autoref{fig:mandelbrot}. +le \btwo~fonctionnait correctement. Ce qui donne la +\hyperref[fig:mandelbrot]{Figure \ref*{fig:mandelbrot}}. \begin{figure}[h!] \centering From 7983e5deb3a44193291cc278ec6304e3021db0c7 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 13:05:39 +0200 Subject: [PATCH 11/35] Revert "ugly fix for an unknown bug" This reverts commit aa51c8b049e0b4e257f64cba758580c056c22259. --- report/document.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/report/document.tex b/report/document.tex index 113c0a7..b5d559c 100644 --- a/report/document.tex +++ b/report/document.tex @@ -283,8 +283,7 @@ en moyenne \approx~10\% de l'utilisation du processeur dans son entièreté. J'ai utilisé un bout de code de \href{https://expreg.org/amsi/C/}{Farès Belhadj} d'un TP de L2 pour afficher une image au format \texttt{bmp} afin vérifier que -le \btwo~fonctionnait correctement. Ce qui donne la -\hyperref[fig:mandelbrot]{Figure \ref*{fig:mandelbrot}}. +le \btwo~fonctionnait correctement. Ce qui donne la \autoref{fig:mandelbrot}. \begin{figure}[h!] \centering From a47cca843dad21e78aa74f7ce339b457f5b07f06 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 13:08:09 +0200 Subject: [PATCH 12/35] remove float module --- report/document.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/report/document.tex b/report/document.tex index b5d559c..1e8a042 100644 --- a/report/document.tex +++ b/report/document.tex @@ -1,4 +1,4 @@ -\DocumentMetadata{testphase = {phase-II,sec,toc,graphic,minipage,float,text}} +\DocumentMetadata{testphase = {phase-II,sec,toc,graphic,minipage,text}} \documentclass[a4paper]{article} \usepackage[T1]{fontenc} % encoding From 98397f71e7a1b14d592c819125631dce5c952c70 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 13:10:51 +0200 Subject: [PATCH 13/35] center caption --- report/document.tex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/report/document.tex b/report/document.tex index 1e8a042..368d94c 100644 --- a/report/document.tex +++ b/report/document.tex @@ -28,6 +28,8 @@ % Images \usepackage{graphicx} +\usepackage{caption} +\captionsetup{justification=centering} \def\titleName{Projet : Un ordonnanceur par work stealing} \def\docTitle{\href{https://www.irif.fr/~jch/enseignement/systeme/projet.pdf}{\titleName}} From 7043d65423150c3fe37f80a897386c46fa2f768e Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 13:18:47 +0200 Subject: [PATCH 14/35] francais --- report/document.tex | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/report/document.tex b/report/document.tex index 368d94c..517bd9f 100644 --- a/report/document.tex +++ b/report/document.tex @@ -82,13 +82,13 @@ Comme cette implémentation n'ordonnance rien et que le nombre de threads créer est important. \subsection{Threads avec pile}\label{desc:th_pile} -Pour cette implémentation, on garde en mémoire une pile, -et on démarre un nombre fixe de threads et à chaque ajout d'une tâche, -on l'empile. Chaque thread récupère la dernière tâche ajoutée à la pile. +Pour cette implémentation, nous gardons en mémoire une pile, +et nous démarrons un nombre fixe de threads et à chaque ajout d'une tâche, +le thread l'empile. Chaque thread récupère la dernière tâche ajoutée à la pile. \subsubsection{Sélection aléatoire de tâche} Même fonctionnement que dans l'algorithme de \docref{desc:th_pile}, sauf -qu'au lieu de récupérer la dernière tâche, on récupère une tâche +qu'au lieu de récupérer la dernière tâche, le thread récupère une tâche aléatoire de la pile. \subsection{Répartition par \ws}\label{desc:ws} @@ -110,6 +110,14 @@ un vol, c'est le dernier élément qui est récupéré par le thread. Dans mes implémentations, j'ai exclusivement utilisé des mutex ainsi que des variables de conditions pour endormir/réveiller mes threads. +Pendant le développement j'ai parfois utilisé \texttt{usleep} au lieu des +variables de conditions pour faire attendre les threads, mais j'ai obtenu de +meilleurs résultats avec les variables de conditions. Aussi je pense qu'avoir +les variables de conditions m'assure que mon ordonnanceur fonctionne sur +n'importe quel CPU, qu'il soit lent ou rapide, avec des performances honnêtes. +En effet, choisir une valeur qui fonctionne bien sur mon ordinateur n'assure pas +qu'elle soit la meilleure pour un autre. + \subsection{Nombre de threads} Pour avoir un programme performant, il faut équilibrer le nombre de threads par rapport aux nombres de \coeur{}s disponibles. Il faut également équilibrer la @@ -206,11 +214,11 @@ et donc il faut gérer les tâches et décider de quelle tâche va sur quel thre Le lancement de nouveau thread étant limité, les performances sont grandement améliorées par rapport aux tests de \docref{stats:th_ges}. -Également grâce au fait que désormais on utilise les \coeur{}s~de notre CPU, +Également grâce au fait que désormais nous utilisons les \coeur{}s~de notre CPU, les performances sont aussi améliorées par rapport aux tests de \docref{stats:seq}. -Dans la \autoref{fig:btm-lifo}, on observe que les \coeur{}s du CPU ne sont pas +Dans la \autoref{fig:btm-lifo}, nous observons que les \coeur{}s du CPU ne sont pas tous utilisé à 100\%. Ceci est dû au fait que l'accès à la liste des tâches est limité, car partagé entres les threads. @@ -241,8 +249,8 @@ limité, car partagé entres les threads. \end{description} Cette implémentation est identique à \docref{stats:stack}, à l'exception que -l'on récupère une tâche aléatoire de la pile au lieu d'y prendre la dernière -ajouté. +les threads récupèrent une tâche aléatoire de la pile au lieu d'y prendre +la dernière ajouté. Cette façon de faire réduit les performances. @@ -265,11 +273,11 @@ Cette façon de faire réduit les performances. \end{description} \end{description} -Dans cet implémentation, on n'utilises plus une pile mais un deque de tâches. +Dans cet implémentation, nous n'utilisons plus une pile mais un deque de tâches. Cette façon de faire est légèrement meilleur que \docref{desc:th_pile}. -Dans la \autoref{fig:btm-ws}, on observe que les \coeur{}s du CPU sont -proche de 100\% d'utilisation. Comparé à \docref{stats:stack}, on gagne +Dans la \autoref{fig:btm-ws}, nous observons que les \coeur{}s du CPU sont +proche de 100\% d'utilisation. Comparé à \docref{stats:stack}, nous gagnons en moyenne \approx~10\% de l'utilisation du processeur dans son entièreté. \begin{figure}[h!] From 1f60916f097503b5273877abfbddea1bd6be56eb Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 13:30:46 +0200 Subject: [PATCH 15/35] typos --- report/document.tex | 50 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/report/document.tex b/report/document.tex index 517bd9f..42b0ce0 100644 --- a/report/document.tex +++ b/report/document.tex @@ -78,13 +78,13 @@ de \texttt{quicksort.c}. Elle lance les tâches sans threads. Cette implémentation correspond à simplement démarrer un nouveau thread pour chaque nouvelle tâche. -Comme cette implémentation n'ordonnance rien et que le nombre de threads créer +Comme cette implémentation n'ordonnance rien et que le nombre de threads créés est important. \subsection{Threads avec pile}\label{desc:th_pile} -Pour cette implémentation, nous gardons en mémoire une pile, -et nous démarrons un nombre fixe de threads et à chaque ajout d'une tâche, -le thread l'empile. Chaque thread récupère la dernière tâche ajoutée à la pile. +Pour cette implémentation, nous gardons en mémoire une pile et nous démarrons +un nombre fixe de threads, et à chaque ajout d'une tâche, le thread l'empile. +Chaque thread récupère la dernière tâche ajoutée à la pile. \subsubsection{Sélection aléatoire de tâche} Même fonctionnement que dans l'algorithme de \docref{desc:th_pile}, sauf @@ -92,8 +92,8 @@ qu'au lieu de récupérer la dernière tâche, le thread récupère une tâche aléatoire de la pile. \subsection{Répartition par \ws}\label{desc:ws} -Ici, chaque \coeur~a sa propre liste de tâche. Quand un thread n'as -plus de tâche, il essaie d'en voler une à un autre thread. +Ici, chaque \coeur~a sa propre liste de tâches. Quand un thread n'a +plus de tâches, il essaie d'en voler une à un autre thread. \section{Comportement} @@ -110,9 +110,9 @@ un vol, c'est le dernier élément qui est récupéré par le thread. Dans mes implémentations, j'ai exclusivement utilisé des mutex ainsi que des variables de conditions pour endormir/réveiller mes threads. -Pendant le développement j'ai parfois utilisé \texttt{usleep} au lieu des +Pendant le développement, j'ai parfois utilisé \texttt{usleep} au lieu des variables de conditions pour faire attendre les threads, mais j'ai obtenu de -meilleurs résultats avec les variables de conditions. Aussi je pense qu'avoir +meilleurs résultats avec les variables de conditions. Aussi, je pense qu'avoir les variables de conditions m'assure que mon ordonnanceur fonctionne sur n'importe quel CPU, qu'il soit lent ou rapide, avec des performances honnêtes. En effet, choisir une valeur qui fonctionne bien sur mon ordinateur n'assure pas @@ -122,11 +122,11 @@ qu'elle soit la meilleure pour un autre. Pour avoir un programme performant, il faut équilibrer le nombre de threads par rapport aux nombres de \coeur{}s disponibles. Il faut également équilibrer la création de nouvelles tâches par thread par rapport au véritable travail -effectué par ledit thread. Par exemple dans le \btwo, chaque tâche soit créer 4 -nouvelles tâches, soit calcule une portion de l'image. Une plus grande création -de tâche favorise le \ws~parce qu'une pile unique atteint ses limites quand -trop de tâches est ajouté, car les threads n'ont pas le temps "d'abattre -le travail" assez rapidement. +effectué par ledit thread. Par exemple, dans le \btwo, chaque tâche soit crée +quatre nouvelles tâches, soit calcule une portion de l'image. Une plus grande +création de tâches favorise le \ws~parce qu'une pile unique atteint ses limites +quand trop de tâches sont ajoutées, car les threads n'ont pas le temps +"d'abattre le travail" assez rapidement. \section{Statistiques} @@ -138,8 +138,8 @@ de \texttt{gcc}, sur 2 machines. \item \textbf{8 \coeur{}s} pour la \mtwo. \end{enumerate} -Le programme utilisé pour tester les implémentations sont le quicksort fourni -et une adaptation de mandelbrot fournis dans le TP10. +Le programme utilisé pour tester les implémentations est le quicksort fourni +et une adaptation de mandelbrot fournie dans le TP10. \subsection{Séquentiel}\label{stats:seq} \begin{description} @@ -183,13 +183,13 @@ Ce programme ne bénéficie pas de toute la puissance de la machine. \end{description} \end{description} -La création des threads pour chaque tâche créer un énorme +La création des threads pour chaque tâche crée un énorme goulot d'étranglement qui réduit de grandement les performances. Le temps d'exécution étant long, nous pouvons voir les threads via la commande \texttt{top} : \mintinline{bash}|top -Hp $(pgrep ordonnanceur)|. -Pour augmenter les performances, il faut avoir une taille fixe de threads créer, +Pour augmenter les performances, il faut avoir une taille fixe de threads crée, et donc il faut gérer les tâches et décider de quelle tâche va sur quel thread. \subsection{Threads avec pile}\label{stats:stack} @@ -211,16 +211,16 @@ et donc il faut gérer les tâches et décider de quelle tâche va sur quel thre \end{description} \end{description} -Le lancement de nouveau thread étant limité, les performances +Le lancement de nouveaux threads étant limité, les performances sont grandement améliorées par rapport aux tests de \docref{stats:th_ges}. -Également grâce au fait que désormais nous utilisons les \coeur{}s~de notre CPU, +Également, grâce au fait que désormais nous utilisons les \coeur{}s~de notre CPU, les performances sont aussi améliorées par rapport aux tests de \docref{stats:seq}. Dans la \autoref{fig:btm-lifo}, nous observons que les \coeur{}s du CPU ne sont pas -tous utilisé à 100\%. Ceci est dû au fait que l'accès à la liste des tâches est -limité, car partagé entres les threads. +tous utilisés à 100 \%. Ceci est dû au fait que l'accès à la liste des tâches est +limité, car partagé entre les threads. \begin{figure}[h!] \centering @@ -250,7 +250,7 @@ limité, car partagé entres les threads. Cette implémentation est identique à \docref{stats:stack}, à l'exception que les threads récupèrent une tâche aléatoire de la pile au lieu d'y prendre -la dernière ajouté. +la dernière ajoutée. Cette façon de faire réduit les performances. @@ -273,12 +273,12 @@ Cette façon de faire réduit les performances. \end{description} \end{description} -Dans cet implémentation, nous n'utilisons plus une pile mais un deque de tâches. +Dans cette implémentation, nous n'utilisons plus une pile, mais un deque de tâches. Cette façon de faire est légèrement meilleur que \docref{desc:th_pile}. Dans la \autoref{fig:btm-ws}, nous observons que les \coeur{}s du CPU sont -proche de 100\% d'utilisation. Comparé à \docref{stats:stack}, nous gagnons -en moyenne \approx~10\% de l'utilisation du processeur dans son entièreté. +proches de 100 \% d'utilisation. Comparé à \docref{stats:stack}, nous gagnons +en moyenne \approx~10 \% de l'utilisation du processeur dans son entièreté. \begin{figure}[h!] \centering From a7be83996d894fb324679bd07f75c87b9406a5ae Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 13:33:35 +0200 Subject: [PATCH 16/35] link to repository --- README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README b/README index 6f860e9..b1d3359 100644 --- a/README +++ b/README @@ -38,4 +38,6 @@ Infos Le rapport se trouve dans le dossier courant. +Lien vers le dépôt : https://git.mylloon.fr/Paris7/work-stealing-scheduler + Anri Kennel 22302653 From 8418a8010ec5f0a21acf06687eccc5382ee02bda Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 17:04:35 +0200 Subject: [PATCH 17/35] fix typos --- README | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README b/README index b1d3359..c3eaad6 100644 --- a/README +++ b/README @@ -21,8 +21,8 @@ Exemple : quicksort en utilisant tous les cœurs disponibles ./ordonnanceur.elf -qt 0 -Cible du makefile --------------- +Cibles du makefile +------------------ Il est possible d'utiliser d'autres implémentations d'ordonnanceur en changeant la cible du Makefile. @@ -33,11 +33,10 @@ la cible du Makefile. * `make ws` : work-stealing -Infos ------ +Informations +------------ Le rapport se trouve dans le dossier courant. - Lien vers le dépôt : https://git.mylloon.fr/Paris7/work-stealing-scheduler Anri Kennel 22302653 From 8ac121d9ef1c42e63f54e36a0cd8363ca80e9165 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 25 Apr 2024 17:07:48 +0200 Subject: [PATCH 18/35] 2 todos --- report/document.tex | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/report/document.tex b/report/document.tex index 42b0ce0..6f8b9d8 100644 --- a/report/document.tex +++ b/report/document.tex @@ -287,6 +287,13 @@ en moyenne \approx~10 \% de l'utilisation du processeur dans son entièreté. \label{fig:btm-ws} \end{figure} +% TODO: Afficher les statistiques de vols (+ parler de la structure qui récupère +% ses données pour bien dire que on les récupère pas à la sauvage) + +\section{Interprétation} +% TODO: Ici il faudrait interpréter les données/statistiques de la section +% du dessus + \clearpage \appendix \section{Crédits} From 5b0b832c29e92ae7744c1cbb0f7217d15c44a64e Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 26 Apr 2024 01:26:16 +0200 Subject: [PATCH 19/35] stats de vol --- report/document.tex | 56 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/report/document.tex b/report/document.tex index 6f8b9d8..17fb451 100644 --- a/report/document.tex +++ b/report/document.tex @@ -17,7 +17,8 @@ % Code integration \usepackage{minted} -\setminted[c]{autogobble,frame=lines} +\setminted[c]{autogobble,frame=lines} % code +\setminted[ada]{autogobble} % stats de vol \usemintedstyle{emacs} % Langages @@ -287,10 +288,59 @@ en moyenne \approx~10 \% de l'utilisation du processeur dans son entièreté. \label{fig:btm-ws} \end{figure} -% TODO: Afficher les statistiques de vols (+ parler de la structure qui récupère -% ses données pour bien dire que on les récupère pas à la sauvage) +Concernant les statistiques de vols, les résultats sont obtenus en récupérant +les données par thread en prenant des précautions pour ne pas dégrader les +performances de l'ordonnanceur. Les données sont récoltées par thread et ensuite +tout est additionné quand toutes les tâches sont terminées. + +\begin{description} + \item[\bone] \hspace{1em} + \begin{description} + \item[\mone] \hspace{1em} + \begin{minted}{ada} + ------- Satistiques ------- + Total tâches : 368439 + Total vols : 5484 + Total vols réussis : 5222 + Total vols échoués : 262 + ---------------------------- + \end{minted} + \item[\mtwo] \hspace{1em} + \begin{minted}{ada} + ------- Satistiques ------- + Total tâches : ??? + Total vols : ??? + Total vols réussis : ??? + Total vols échoués : ??? + ---------------------------- + \end{minted} + \end{description} + + \item[\btwo] \hspace{1em} + \begin{description} + \item[\mone] \hspace{1em} + \begin{minted}{ada} + ------- Statistiques ------- + Total tâches : 873813 + Total vols : 23232 + Total vols réussis : 23192 + Total vols échoués : 40 + ---------------------------- + \end{minted} + \item[\mtwo] \hspace{1em} + \begin{minted}{ada} + ------- Satistiques ------- + Total tâches : ??? + Total vols : ??? + Total vols réussis : ??? + Total vols échoués : ??? + ---------------------------- + \end{minted} + \end{description} +\end{description} \section{Interprétation} +\dots % TODO: Ici il faudrait interpréter les données/statistiques de la section % du dessus From e731d4bb54c5b17870cbad70913cba6d37dd234d Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 26 Apr 2024 01:30:32 +0200 Subject: [PATCH 20/35] m2 --- report/document.tex | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/report/document.tex b/report/document.tex index 17fb451..2035769 100644 --- a/report/document.tex +++ b/report/document.tex @@ -307,11 +307,11 @@ tout est additionné quand toutes les tâches sont terminées. \end{minted} \item[\mtwo] \hspace{1em} \begin{minted}{ada} - ------- Satistiques ------- - Total tâches : ??? - Total vols : ??? - Total vols réussis : ??? - Total vols échoués : ??? + ------- Statistiques ------- + Total tâches : 368439 + Total vols : 2298 + Total vols réussis : 2164 + Total vols échoués : 134 ---------------------------- \end{minted} \end{description} @@ -329,11 +329,11 @@ tout est additionné quand toutes les tâches sont terminées. \end{minted} \item[\mtwo] \hspace{1em} \begin{minted}{ada} - ------- Satistiques ------- - Total tâches : ??? - Total vols : ??? - Total vols réussis : ??? - Total vols échoués : ??? + ------- Statistiques ------- + Total tâches : 873813 + Total vols : 21491 + Total vols réussis : 21465 + Total vols échoués : 26 ---------------------------- \end{minted} \end{description} From 3c2b0832d36d6213bbfe372c48d7d51f930d9a6c Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 26 Apr 2024 01:44:06 +0200 Subject: [PATCH 21/35] interp --- report/document.tex | 48 +++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/report/document.tex b/report/document.tex index 2035769..6b12ccd 100644 --- a/report/document.tex +++ b/report/document.tex @@ -1,8 +1,11 @@ \DocumentMetadata{testphase = {phase-II,sec,toc,graphic,minipage,text}} \documentclass[a4paper]{article} + +% Fonts \usepackage[T1]{fontenc} % encoding -\renewcommand{\familydefault}{\sfdefault} % sans-serif font +\renewcommand{\familydefault}{\sfdefault} % sans-serif + % Add \extra info to title \makeatletter @@ -15,24 +18,38 @@ } \makeatother + % Code integration \usepackage{minted} \setminted[c]{autogobble,frame=lines} % code \setminted[ada]{autogobble} % stats de vol \usemintedstyle{emacs} + % Langages \usepackage[french]{babel} \frenchsetup{SmallCapsFigTabCaptions=false} \usepackage{csquotes} \MakeOuterQuote{"} + % Images \usepackage{graphicx} \usepackage{caption} \captionsetup{justification=centering} -\def\titleName{Projet : Un ordonnanceur par work stealing} + +% Aliases +\def\coeur{c\oe{}ur} +\def\mone{\textit{Machine 1}} % fixe +\def\mtwo{\textit{Machine 2}} % portable +\def\bone{\textit{Benchmark quicksort}} +\def\btwo{\textit{Benchmark mandelbrot}} +\def\ws{\enquote{work-stealing}} + + +% Metadatas +\def\titleName{Projet : Un ordonnanceur par \ws} \def\docTitle{\href{https://www.irif.fr/~jch/enseignement/systeme/projet.pdf}{\titleName}} \def\anri{Anri Kennel} @@ -52,15 +69,10 @@ \extra{\docSubject~$\cdot$ \docLocation} \date{Année universitaire 2023-2024} + +% Commands \newcommand{\docref}[1]{\textit{\nameref{#1}}} % italic nameref -% Aliases -\def\coeur{c\oe{}ur} -\def\mone{\textit{Machine 1}} % fixe -\def\mtwo{\textit{Machine 2}} % portable -\def\bone{\textit{Benchmark quicksort}} -\def\btwo{\textit{Benchmark mandelbrot}} -\def\ws{\enquote{work-stealing}} \begin{document} \maketitle @@ -68,6 +80,7 @@ \tableofcontents \clearpage + \section{Descriptions} Description des différents algorithmes implémentés. @@ -129,7 +142,8 @@ création de tâches favorise le \ws~parce qu'une pile unique atteint ses limite quand trop de tâches sont ajoutées, car les threads n'ont pas le temps "d'abattre le travail" assez rapidement. -\section{Statistiques} + +\section{Statistiques}\label{sec:stats} Chaque implémentation a été testée avec l'optimisation de niveau 2 de \texttt{gcc}, sur 2 machines. @@ -339,10 +353,18 @@ tout est additionné quand toutes les tâches sont terminées. \end{description} \end{description} +Nous pouvons remarquer que moins il y a de vols échoués, +meilleur est le temps d'exécution. Également, le nombre de vols échoués est +faible quand beaucoup de tâches sont créées, car la probabilité qu'un thread ait +des tâches en attente est plus grande. + + \section{Interprétation} -\dots -% TODO: Ici il faudrait interpréter les données/statistiques de la section -% du dessus +En se basant sur les résultats des tests de \docref{sec:stats}, on remarque +que l'algorithme de \ws~est le plus performant dans la \mone~ainsi que dans +la \mtwo. Nous voyons aussi que ce système profite d'un grand nombre de +tâches créées, car le \btwo~créant quatre tâches d'un coup provoque nettement +moins de vol comparé au \bone~qui n'en crée que deux. \clearpage \appendix From c8817d3ec3a448d04934a4146746ce9c9ff9f5ff Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 26 Apr 2024 02:15:19 +0200 Subject: [PATCH 22/35] clean data --- report/data/machine1-mandelbrot.csv | 2 -- report/data/machine1-quicksort.csv | 2 -- report/data/machine2-mandelbrot.csv | 2 -- report/data/machine2-mandelbrot1.csv | 7 +++++++ report/data/machine2-mandelbrot2.csv | 7 +++++++ report/data/machine2-quicksort.csv | 2 -- 6 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 report/data/machine2-mandelbrot1.csv create mode 100644 report/data/machine2-mandelbrot2.csv diff --git a/report/data/machine1-mandelbrot.csv b/report/data/machine1-mandelbrot.csv index 7a1cda0..2b4beab 100644 --- a/report/data/machine1-mandelbrot.csv +++ b/report/data/machine1-mandelbrot.csv @@ -99,5 +99,3 @@ serial;solution1;solution2;solution3;solution4 ;;0,777302;0,707086;0,422294 ;;0,786113;0,721242;0,45898 ;;0,779815;0,718811;0,419718 -;;;; -=AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101) diff --git a/report/data/machine1-quicksort.csv b/report/data/machine1-quicksort.csv index 9b7e7be..59a2d96 100644 --- a/report/data/machine1-quicksort.csv +++ b/report/data/machine1-quicksort.csv @@ -99,5 +99,3 @@ serial;solution1;solution2;solution3;solution4 0,848781;;0,255499;0,38121;0,240645 0,843061;;0,258374;0,413357;0,227622 0,848842;;0,262713;0,383977;0,219846 -;;;; -=AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101) diff --git a/report/data/machine2-mandelbrot.csv b/report/data/machine2-mandelbrot.csv index 0f98b18..f0af87e 100644 --- a/report/data/machine2-mandelbrot.csv +++ b/report/data/machine2-mandelbrot.csv @@ -99,5 +99,3 @@ serial;solution1;solution2;solution3;solution4 ;;1,855647;2,02672;1,118689 ;;1,876364;2,004184;1,093833 ;;1,855262;2,000091;1,120682 -;;;; -=AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101) diff --git a/report/data/machine2-mandelbrot1.csv b/report/data/machine2-mandelbrot1.csv new file mode 100644 index 0000000..8451689 --- /dev/null +++ b/report/data/machine2-mandelbrot1.csv @@ -0,0 +1,7 @@ +solution4 +1.2 +1.5 +1.7 +1.8 +2.0 +% Add more data here if available diff --git a/report/data/machine2-mandelbrot2.csv b/report/data/machine2-mandelbrot2.csv new file mode 100644 index 0000000..b6f5536 --- /dev/null +++ b/report/data/machine2-mandelbrot2.csv @@ -0,0 +1,7 @@ +solution4 +1.0 +1.3 +1.6 +1.9 +2.2 +% Add more data here if available diff --git a/report/data/machine2-quicksort.csv b/report/data/machine2-quicksort.csv index 04f7c7e..0e77e5d 100644 --- a/report/data/machine2-quicksort.csv +++ b/report/data/machine2-quicksort.csv @@ -99,5 +99,3 @@ serial;solution1;solution2;solution3;solution4 1,133824;;0,425726;0,461766;0,302243 1,131027;;0,417199;0,467319;0,312465 1,138425;;0,386066;0,459411;0,321559 -;;;; -=AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101) From dc9738e4fe07655c62c8741fe479852e75155988 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 26 Apr 2024 02:15:35 +0200 Subject: [PATCH 23/35] typos --- report/document.tex | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/report/document.tex b/report/document.tex index 6b12ccd..770ffba 100644 --- a/report/document.tex +++ b/report/document.tex @@ -154,7 +154,8 @@ de \texttt{gcc}, sur 2 machines. \end{enumerate} Le programme utilisé pour tester les implémentations est le quicksort fourni -et une adaptation de mandelbrot fournie dans le TP10. +et une adaptation de mandelbrot fournie dans le +\href{https://www.irif.fr/~jch/enseignement/systeme/tp10.pdf}{TP 10}. \subsection{Séquentiel}\label{stats:seq} \begin{description} @@ -353,10 +354,10 @@ tout est additionné quand toutes les tâches sont terminées. \end{description} \end{description} -Nous pouvons remarquer que moins il y a de vols échoués, -meilleur est le temps d'exécution. Également, le nombre de vols échoués est -faible quand beaucoup de tâches sont créées, car la probabilité qu'un thread ait -des tâches en attente est plus grande. +Nous pouvons remarquer que moins il y a de vols échoués, meilleur est +le temps d'exécution. Également, le nombre de vols échoués est faible quand +beaucoup de tâches sont créées, car la probabilité qu'un thread ait des tâches +en attente est plus grande. \section{Interprétation} From a022140f3ddb989dd0eed5907962a5a44f644427 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 26 Apr 2024 03:00:55 +0200 Subject: [PATCH 24/35] Add graphics+ small fixes --- report/document.tex | 94 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 10 deletions(-) diff --git a/report/document.tex b/report/document.tex index 770ffba..4740bcb 100644 --- a/report/document.tex +++ b/report/document.tex @@ -33,12 +33,6 @@ \MakeOuterQuote{"} -% Images -\usepackage{graphicx} -\usepackage{caption} -\captionsetup{justification=centering} - - % Aliases \def\coeur{c\oe{}ur} \def\mone{\textit{Machine 1}} % fixe @@ -48,8 +42,18 @@ \def\ws{\enquote{work-stealing}} +% Plots +\usepackage{pgfplots} +\pgfplotsset{compat=1.11} + +% Images +\usepackage{graphicx} +\usepackage{caption} +\captionsetup{justification=centering} + + % Metadatas -\def\titleName{Projet : Un ordonnanceur par \ws} +\def\titleName{Projet : Un ordonnanceur par work-stealing} \def\docTitle{\href{https://www.irif.fr/~jch/enseignement/systeme/projet.pdf}{\titleName}} \def\anri{Anri Kennel} @@ -72,7 +76,68 @@ % Commands \newcommand{\docref}[1]{\textit{\nameref{#1}}} % italic nameref +\newcommand{\statPlot}[1]{ % Plot for stats + \begin{figure}[H] + \def\side{0.5\textwidth} + \def\width{\textwidth} + \def\height{0.7\textwidth} + \def\xlabel{Itérations} + \def\ylabel{Secondes} + \def\colname{#1} + \begin{minipage}{\side} + \centering + \begin{tikzpicture} + \begin{axis}[ + xlabel={\xlabel}, + ylabel={\ylabel}, + width=\width, + height=\height + ] + \addplot [smooth, color=red] table [ + x expr=\coordindex, + y=\colname, + col sep=semicolon, + /pgf/number format/read comma as period] {data/machine1-quicksort.csv}; + + \addplot [smooth, color=blue] table [ + x expr=\coordindex, + y=\colname, + col sep=semicolon, + /pgf/number format/read comma as period] {data/machine2-quicksort.csv}; + \end{axis} + \end{tikzpicture} + \caption{Temps d'exécution pour \bone} + \end{minipage}\hfill + \begin{minipage}{\side} + \centering + \begin{tikzpicture} + \begin{axis}[ + xlabel={\xlabel}, + ylabel={\ylabel}, + legend pos=outer north east, + width=\width, + height=\height + ] + \addplot [smooth, color=red] table [ + x expr=\coordindex, + y=\colname, + col sep=semicolon, + /pgf/number format/read comma as period] {data/machine1-mandelbrot.csv}; + \addlegendentry{\mone} + + \addplot [smooth, color=blue] table [ + x expr=\coordindex, + y=\colname, + col sep=semicolon, + /pgf/number format/read comma as period] {data/machine2-mandelbrot.csv}; + \addlegendentry{\mtwo} + \end{axis} + \end{tikzpicture} + \caption{Temps d'exécution pour \btwo} + \end{minipage} + \end{figure} +} \begin{document} \maketitle @@ -176,6 +241,7 @@ et une adaptation de mandelbrot fournie dans le \end{description} \end{description} +\statPlot{serial} Ce programme ne bénéficie pas de toute la puissance de la machine. @@ -199,6 +265,8 @@ Ce programme ne bénéficie pas de toute la puissance de la machine. \end{description} \end{description} +\statPlot{solution1} + La création des threads pour chaque tâche crée un énorme goulot d'étranglement qui réduit de grandement les performances. @@ -227,6 +295,8 @@ et donc il faut gérer les tâches et décider de quelle tâche va sur quel thre \end{description} \end{description} +\statPlot{solution2} + Le lancement de nouveaux threads étant limité, les performances sont grandement améliorées par rapport aux tests de \docref{stats:th_ges}. @@ -238,7 +308,7 @@ Dans la \autoref{fig:btm-lifo}, nous observons que les \coeur{}s du CPU ne sont tous utilisés à 100 \%. Ceci est dû au fait que l'accès à la liste des tâches est limité, car partagé entre les threads. -\begin{figure}[h!] +\begin{figure}[H] \centering \includegraphics[alt={Graphique},width=\textwidth]{imgs/bottom-lifo.jpg} \caption{Utilisation ressources sur la \mone~avec \docref{desc:th_pile}} @@ -264,6 +334,8 @@ limité, car partagé entre les threads. \end{description} \end{description} +\statPlot{solution3} + Cette implémentation est identique à \docref{stats:stack}, à l'exception que les threads récupèrent une tâche aléatoire de la pile au lieu d'y prendre la dernière ajoutée. @@ -289,6 +361,8 @@ Cette façon de faire réduit les performances. \end{description} \end{description} +\statPlot{solution4} + Dans cette implémentation, nous n'utilisons plus une pile, mais un deque de tâches. Cette façon de faire est légèrement meilleur que \docref{desc:th_pile}. @@ -296,7 +370,7 @@ Dans la \autoref{fig:btm-ws}, nous observons que les \coeur{}s du CPU sont proches de 100 \% d'utilisation. Comparé à \docref{stats:stack}, nous gagnons en moyenne \approx~10 \% de l'utilisation du processeur dans son entièreté. -\begin{figure}[h!] +\begin{figure}[H] \centering \includegraphics[alt={Graphique},width=\textwidth]{imgs/bottom-ws.jpg} \caption{Exploitation des ressources sur la \mone~avec \docref{desc:ws}} @@ -375,7 +449,7 @@ J'ai utilisé un bout de code de \href{https://expreg.org/amsi/C/}{Farès Belhad d'un TP de L2 pour afficher une image au format \texttt{bmp} afin vérifier que le \btwo~fonctionnait correctement. Ce qui donne la \autoref{fig:mandelbrot}. -\begin{figure}[h!] +\begin{figure}[H] \centering \includegraphics[alt={Fractale mandelbrot},width=0.7\textwidth]{imgs/mandelbrot.jpg} \caption{Example de Mandelbrot} From cf0fc61a2422abfc9f8102514cfb81b6caf3d62b Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 26 Apr 2024 03:10:46 +0200 Subject: [PATCH 25/35] add btm credits --- report/document.tex | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/report/document.tex b/report/document.tex index 4740bcb..3dfa5a2 100644 --- a/report/document.tex +++ b/report/document.tex @@ -456,4 +456,8 @@ le \btwo~fonctionnait correctement. Ce qui donne la \autoref{fig:mandelbrot}. \label{fig:mandelbrot} \end{figure} +Les captures d'écran de la \autoref{fig:btm-lifo} et de la \autoref{fig:btm-ws} +ont été prises via le +programme \href{https://github.com/ClementTsang/bottom}{bottom}. + \end{document} From f271870c93690fb3aa44eb35cc474537e443fb36 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 26 Apr 2024 03:19:13 +0200 Subject: [PATCH 26/35] small fixes --- report/document.tex | 88 ++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 40 deletions(-) diff --git a/report/document.tex b/report/document.tex index 3dfa5a2..7a7c357 100644 --- a/report/document.tex +++ b/report/document.tex @@ -76,7 +76,7 @@ % Commands \newcommand{\docref}[1]{\textit{\nameref{#1}}} % italic nameref -\newcommand{\statPlot}[1]{ % Plot for stats +\newcommand{\statPlot}[2]{ % Plot for stats \begin{figure}[H] \def\side{0.5\textwidth} \def\width{\textwidth} @@ -107,7 +107,7 @@ /pgf/number format/read comma as period] {data/machine2-quicksort.csv}; \end{axis} \end{tikzpicture} - \caption{Temps d'exécution pour \bone} + \caption{Temps d'exécution pour \bone~\textit{#2}} \end{minipage}\hfill \begin{minipage}{\side} \centering @@ -134,7 +134,7 @@ \addlegendentry{\mtwo} \end{axis} \end{tikzpicture} - \caption{Temps d'exécution pour \btwo} + \caption{Temps d'exécution pour \btwo~\textit{#2}} \end{minipage} \end{figure} } @@ -241,7 +241,7 @@ et une adaptation de mandelbrot fournie dans le \end{description} \end{description} -\statPlot{serial} +\statPlot{serial}{en séquentiel} Ce programme ne bénéficie pas de toute la puissance de la machine. @@ -265,7 +265,7 @@ Ce programme ne bénéficie pas de toute la puissance de la machine. \end{description} \end{description} -\statPlot{solution1} +\statPlot{solution1}{avec des threads} La création des threads pour chaque tâche crée un énorme goulot d'étranglement qui réduit de grandement les performances. @@ -295,7 +295,7 @@ et donc il faut gérer les tâches et décider de quelle tâche va sur quel thre \end{description} \end{description} -\statPlot{solution2} +\statPlot{solution2}{avec LIFO} Le lancement de nouveaux threads étant limité, les performances sont grandement améliorées par rapport aux tests de \docref{stats:th_ges}. @@ -334,7 +334,7 @@ limité, car partagé entre les threads. \end{description} \end{description} -\statPlot{solution3} +\statPlot{solution3}{avec LIFO aléatoire} Cette implémentation est identique à \docref{stats:stack}, à l'exception que les threads récupèrent une tâche aléatoire de la pile au lieu d'y prendre @@ -361,7 +361,7 @@ Cette façon de faire réduit les performances. \end{description} \end{description} -\statPlot{solution4} +\statPlot{solution4}{avec du \ws} Dans cette implémentation, nous n'utilisons plus une pile, mais un deque de tâches. Cette façon de faire est légèrement meilleur que \docref{desc:th_pile}. @@ -386,45 +386,53 @@ tout est additionné quand toutes les tâches sont terminées. \item[\bone] \hspace{1em} \begin{description} \item[\mone] \hspace{1em} - \begin{minted}{ada} - ------- Satistiques ------- - Total tâches : 368439 - Total vols : 5484 - Total vols réussis : 5222 - Total vols échoués : 262 - ---------------------------- - \end{minted} + \begin{samepage} + \begin{minted}{ada} + ------- Satistiques ------- + Total tâches : 368439 + Total vols : 5484 + Total vols réussis : 5222 + Total vols échoués : 262 + ---------------------------- + \end{minted} + \end{samepage} \item[\mtwo] \hspace{1em} - \begin{minted}{ada} - ------- Statistiques ------- - Total tâches : 368439 - Total vols : 2298 - Total vols réussis : 2164 - Total vols échoués : 134 - ---------------------------- - \end{minted} + \begin{samepage} + \begin{minted}{ada} + ------- Statistiques ------- + Total tâches : 368439 + Total vols : 2298 + Total vols réussis : 2164 + Total vols échoués : 134 + ---------------------------- + \end{minted} + \end{samepage} \end{description} \item[\btwo] \hspace{1em} \begin{description} \item[\mone] \hspace{1em} - \begin{minted}{ada} - ------- Statistiques ------- - Total tâches : 873813 - Total vols : 23232 - Total vols réussis : 23192 - Total vols échoués : 40 - ---------------------------- - \end{minted} + \begin{samepage} + \begin{minted}{ada} + ------- Statistiques ------- + Total tâches : 873813 + Total vols : 23232 + Total vols réussis : 23192 + Total vols échoués : 40 + ---------------------------- + \end{minted} + \end{samepage} \item[\mtwo] \hspace{1em} - \begin{minted}{ada} - ------- Statistiques ------- - Total tâches : 873813 - Total vols : 21491 - Total vols réussis : 21465 - Total vols échoués : 26 - ---------------------------- - \end{minted} + \begin{samepage} + \begin{minted}{ada} + ------- Statistiques ------- + Total tâches : 873813 + Total vols : 21491 + Total vols réussis : 21465 + Total vols échoués : 26 + ---------------------------- + \end{minted} + \end{samepage} \end{description} \end{description} From 961e6108f91d262f64f662db8fd69d5f4e990b4f Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 26 Apr 2024 13:05:00 +0200 Subject: [PATCH 27/35] rewording+add some graphs --- report/document.tex | 98 ++++++++++++++++++++++----------- report/imgs/bottom-seq.jpg | Bin 0 -> 32395 bytes report/imgs/bottom-threads.jpg | Bin 0 -> 43475 bytes 3 files changed, 65 insertions(+), 33 deletions(-) create mode 100644 report/imgs/bottom-seq.jpg create mode 100644 report/imgs/bottom-threads.jpg diff --git a/report/document.tex b/report/document.tex index 7a7c357..413f351 100644 --- a/report/document.tex +++ b/report/document.tex @@ -37,8 +37,10 @@ \def\coeur{c\oe{}ur} \def\mone{\textit{Machine 1}} % fixe \def\mtwo{\textit{Machine 2}} % portable -\def\bone{\textit{Benchmark quicksort}} -\def\btwo{\textit{Benchmark mandelbrot}} +\def\qs{\enquote{quicksort}} +\def\mandel{\enquote{mandelbrot}} +\def\bone{\textit{Benchmark \qs}} +\def\btwo{\textit{Benchmark \mandel}} \def\ws{\enquote{work-stealing}} @@ -149,17 +151,13 @@ \section{Descriptions} Description des différents algorithmes implémentés. -\subsection{Séquentiel} -Cette implémentation naïve correspond au mode \texttt{serial} -de \texttt{quicksort.c}. Elle lance les tâches sans threads. +\subsection{Séquentiel}\label{desc:seq} +Cette implémentation lance les tâches sur un \coeur. -\subsection[Threads sans gestion]{Threads sans gestion} +\subsection{Threads sans gestion}\label{desc:threads} Cette implémentation correspond à simplement démarrer un nouveau thread pour chaque nouvelle tâche. -Comme cette implémentation n'ordonnance rien et que le nombre de threads créés -est important. - \subsection{Threads avec pile}\label{desc:th_pile} Pour cette implémentation, nous gardons en mémoire une pile et nous démarrons un nombre fixe de threads, et à chaque ajout d'une tâche, le thread l'empile. @@ -177,6 +175,12 @@ plus de tâches, il essaie d'en voler une à un autre thread. \section{Comportement} +Analyse du comportement des différentes implémentations. + +\subsection{Threads sans gestion} +Cette implémentation n'ordonnance rien, alors le nombre de threads +créés est important. + \subsection{Listes} Dans l'ordonnanceur LIFO, la liste est une pile. Chaque thread récupère le premier élément de la pile, c'est-à-dire le dernier à avoir été ajouté. @@ -189,19 +193,19 @@ un vol, c'est le dernier élément qui est récupéré par le thread. Dans mes implémentations, j'ai exclusivement utilisé des mutex ainsi que des variables de conditions pour endormir/réveiller mes threads. -Pendant le développement, j'ai parfois utilisé \texttt{usleep} au lieu des -variables de conditions pour faire attendre les threads, mais j'ai obtenu de -meilleurs résultats avec les variables de conditions. Aussi, je pense qu'avoir -les variables de conditions m'assure que mon ordonnanceur fonctionne sur -n'importe quel CPU, qu'il soit lent ou rapide, avec des performances honnêtes. -En effet, choisir une valeur qui fonctionne bien sur mon ordinateur n'assure pas -qu'elle soit la meilleure pour un autre. +Pendant le développement, j'ai parfois utilisé \texttt{usleep} pour interrompre +à temps donné un thread au lieu des variables de conditions pour faire +attendre les threads, mais j'ai obtenu de meilleurs résultats avec les variables +de conditions. Aussi, je pense qu'avoir les variables de conditions m'assure +que mon ordonnanceur fonctionne sur n'importe quel CPU, qu'il soit lent ou rapide, +avec des performances honnêtes. En effet, choisir une valeur qui fonctionne bien +sur mon ordinateur n'assure pas qu'elle soit la meilleure pour un autre processeur. \subsection{Nombre de threads} Pour avoir un programme performant, il faut équilibrer le nombre de threads par rapport aux nombres de \coeur{}s disponibles. Il faut également équilibrer la création de nouvelles tâches par thread par rapport au véritable travail -effectué par ledit thread. Par exemple, dans le \btwo, chaque tâche soit crée +effectué par ledit thread. Par exemple, dans le \btwo, chaque tâche crée soit quatre nouvelles tâches, soit calcule une portion de l'image. Une plus grande création de tâches favorise le \ws~parce qu'une pile unique atteint ses limites quand trop de tâches sont ajoutées, car les threads n'ont pas le temps @@ -218,10 +222,19 @@ de \texttt{gcc}, sur 2 machines. \item \textbf{8 \coeur{}s} pour la \mtwo. \end{enumerate} -Le programme utilisé pour tester les implémentations est le quicksort fourni -et une adaptation de mandelbrot fournie dans le +Les benchmarks utilisés pour tester les implémentations sont le \qs~fourni +et une adaptation de \mandel~fournie dans le \href{https://www.irif.fr/~jch/enseignement/systeme/tp10.pdf}{TP 10}. +Pour lancer plusieurs fois le programme, j'ai utilisé la commande +\mintinline{fish}|for| du shell \texttt{fish}. Pour exemple, voici la commande +pour lancer l'ordonnanceur 100 fois avec \qs~et tous les threads disponibles : + +\begin{figure}[H] + \centering + \mintinline{fish}|for i in (seq 100); ./ordonnanceur.elf -qt 0; end| +\end{figure} + \subsection{Séquentiel}\label{stats:seq} \begin{description} \item[\bone] \hspace{1em} @@ -243,7 +256,16 @@ et une adaptation de mandelbrot fournie dans le \statPlot{serial}{en séquentiel} -Ce programme ne bénéficie pas de toute la puissance de la machine. +\begin{figure}[H] + \centering + \includegraphics[alt={Graphique},width=\textwidth]{imgs/bottom-seq.jpg} + \caption{Exploitation des ressources sur la \mone~avec \docref{desc:seq}} + \label{fig:btm-seq} +\end{figure} + +Ce programme ne bénéficie pas de toute la puissance de la machine, +visible notamment grâce à la \autoref{fig:btm-seq} où l'on voit que seulement +un \coeur~est utilisé. \subsection{Threads sans gestion}\label{stats:th_ges} @@ -267,14 +289,25 @@ Ce programme ne bénéficie pas de toute la puissance de la machine. \statPlot{solution1}{avec des threads} -La création des threads pour chaque tâche crée un énorme -goulot d'étranglement qui réduit de grandement les performances. +\begin{figure}[H] + \centering + \includegraphics[alt={Graphique},width=\textwidth]{imgs/bottom-threads.jpg} + \caption{Exploitation des ressources sur la \mone~avec \docref{desc:threads}} + \label{fig:btm-threads} +\end{figure} -Le temps d'exécution étant long, nous pouvons voir les threads via la commande -\texttt{top} : \mintinline{bash}|top -Hp $(pgrep ordonnanceur)|. +La création des threads pour chaque tâche crée un énorme goulot +d'étranglement qui réduit grandement les performances. On le voit notamment +sur la \autoref{fig:btm-threads} où tous les \coeur{}s sont utilisés, mais très +peu. Créer de façon incontrôlée des threads n'est pas une manière efficace de +répartir la charge. -Pour augmenter les performances, il faut avoir une taille fixe de threads crée, -et donc il faut gérer les tâches et décider de quelle tâche va sur quel thread. +% Le temps d'exécution étant long, nous pouvons voir les threads avec la commande +% \texttt{top} : \mintinline{bash}|top -Hp $(pgrep ordonnanceur)|. + +Pour augmenter les performances, il faut donc avoir une taille fixe de threads, +et par conséquent, il faut gérer les tâches et décider de quelle tâche va sur +quel thread. \subsection{Threads avec pile}\label{stats:stack} \begin{description} @@ -305,7 +338,7 @@ les performances sont aussi améliorées par rapport aux tests de \docref{stats:seq}. Dans la \autoref{fig:btm-lifo}, nous observons que les \coeur{}s du CPU ne sont pas -tous utilisés à 100 \%. Ceci est dû au fait que l'accès à la liste des tâches est +tous utilisés à 100~\%. Ceci est dû au fait que l'accès à la liste des tâches est limité, car partagé entre les threads. \begin{figure}[H] @@ -367,8 +400,8 @@ Dans cette implémentation, nous n'utilisons plus une pile, mais un deque de tâ Cette façon de faire est légèrement meilleur que \docref{desc:th_pile}. Dans la \autoref{fig:btm-ws}, nous observons que les \coeur{}s du CPU sont -proches de 100 \% d'utilisation. Comparé à \docref{stats:stack}, nous gagnons -en moyenne \approx~10 \% de l'utilisation du processeur dans son entièreté. +proches de 100~\% d'utilisation. Comparé à \docref{stats:stack}, nous gagnons +en moyenne \approx~10~\% de l'utilisation du processeur dans son entièreté. \begin{figure}[H] \centering @@ -459,13 +492,12 @@ le \btwo~fonctionnait correctement. Ce qui donne la \autoref{fig:mandelbrot}. \begin{figure}[H] \centering - \includegraphics[alt={Fractale mandelbrot},width=0.7\textwidth]{imgs/mandelbrot.jpg} - \caption{Example de Mandelbrot} + \includegraphics[alt={Fractale \mandel},width=0.7\textwidth]{imgs/mandelbrot.jpg} + \caption{Example de \mandel} \label{fig:mandelbrot} \end{figure} -Les captures d'écran de la \autoref{fig:btm-lifo} et de la \autoref{fig:btm-ws} -ont été prises via le +Les captures d'écran d'exploitation des ressources ont été prises via le programme \href{https://github.com/ClementTsang/bottom}{bottom}. \end{document} diff --git a/report/imgs/bottom-seq.jpg b/report/imgs/bottom-seq.jpg new file mode 100644 index 0000000000000000000000000000000000000000..de8889a440775c9af4dd41e4ed8271e1596ff112 GIT binary patch literal 32395 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 literal 0 HcmV?d00001 diff --git a/report/imgs/bottom-threads.jpg b/report/imgs/bottom-threads.jpg new file mode 100644 index 0000000000000000000000000000000000000000..730aadf5e82718cc3623b9f1159f969cf7404e3f GIT binary patch literal 43475 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 Date: Fri, 26 Apr 2024 13:13:50 +0200 Subject: [PATCH 28/35] typo --- report/document.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/report/document.tex b/report/document.tex index 413f351..546200b 100644 --- a/report/document.tex +++ b/report/document.tex @@ -78,7 +78,7 @@ % Commands \newcommand{\docref}[1]{\textit{\nameref{#1}}} % italic nameref -\newcommand{\statPlot}[2]{ % Plot for stats +\newcommand{\statPlot}[2]{ % plot for stats \begin{figure}[H] \def\side{0.5\textwidth} \def\width{\textwidth} From f19a1afc6535cac475942d5a468e66addf7f6fb5 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 26 Apr 2024 13:14:44 +0200 Subject: [PATCH 29/35] what is this? --- report/data/machine2-mandelbrot1.csv | 7 ------- report/data/machine2-mandelbrot2.csv | 7 ------- 2 files changed, 14 deletions(-) delete mode 100644 report/data/machine2-mandelbrot1.csv delete mode 100644 report/data/machine2-mandelbrot2.csv diff --git a/report/data/machine2-mandelbrot1.csv b/report/data/machine2-mandelbrot1.csv deleted file mode 100644 index 8451689..0000000 --- a/report/data/machine2-mandelbrot1.csv +++ /dev/null @@ -1,7 +0,0 @@ -solution4 -1.2 -1.5 -1.7 -1.8 -2.0 -% Add more data here if available diff --git a/report/data/machine2-mandelbrot2.csv b/report/data/machine2-mandelbrot2.csv deleted file mode 100644 index b6f5536..0000000 --- a/report/data/machine2-mandelbrot2.csv +++ /dev/null @@ -1,7 +0,0 @@ -solution4 -1.0 -1.3 -1.6 -1.9 -2.2 -% Add more data here if available From 0731dedeef36b8b0bc30854ee940ba4b5ee68413 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Sat, 27 Apr 2024 11:17:33 +0200 Subject: [PATCH 30/35] newline --- report/document.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/report/document.tex b/report/document.tex index 546200b..c65f531 100644 --- a/report/document.tex +++ b/report/document.tex @@ -48,6 +48,7 @@ \usepackage{pgfplots} \pgfplotsset{compat=1.11} + % Images \usepackage{graphicx} \usepackage{caption} From 12f71e8f482d7ddb52f29195ae228b56eac7e249 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 2 May 2024 23:52:22 +0200 Subject: [PATCH 31/35] add microtype --- report/document.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/report/document.tex b/report/document.tex index c65f531..31f8d7b 100644 --- a/report/document.tex +++ b/report/document.tex @@ -5,6 +5,7 @@ % Fonts \usepackage[T1]{fontenc} % encoding \renewcommand{\familydefault}{\sfdefault} % sans-serif +\usepackage[nopatch=footnote]{microtype} % better font looking % Add \extra info to title From a5f7554d6b4797c6d70d5110064bb978c2a045a3 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 3 May 2024 20:26:04 +0200 Subject: [PATCH 32/35] gzip archive --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index c891408..ea29826 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = gcc RM = rm -rf -TAR = tar -cf +TAR = tar -czf CP = cp -r MKDIR = mkdir -p @@ -63,11 +63,11 @@ pdf-clean: $(MAKE) clean clean: pdf-clean - $(RM) $(ALL_OBJECTS) "$(EXE)$(EXE_EXT)" "$(ARCHIVE_NAME).tar" + $(RM) $(ALL_OBJECTS) "$(EXE)$(EXE_EXT)" "$(ARCHIVE_NAME).tar.gz" archive: pdf-make $(MKDIR) "$(ARCHIVE_NAME)" $(CP) "$(SRC_DIR)" "$(INC_DIR)" Makefile README "$(ARCHIVE_NAME)" $(CP) "$(wildcard $(PDF_DIR)/*.pdf)" "$(ARCHIVE_NAME)/$(PDF_NEWNAME).pdf" - $(TAR) "$(ARCHIVE_NAME).tar" "$(ARCHIVE_NAME)" + $(TAR) "$(ARCHIVE_NAME).tar.gz" "$(ARCHIVE_NAME)" $(RM) "$(ARCHIVE_NAME)" From 692a69a9c4474654f6c45e1b8537ed413b88e64c Mon Sep 17 00:00:00 2001 From: Mylloon Date: Sun, 5 May 2024 14:12:00 +0200 Subject: [PATCH 33/35] retry when possible --- src/mandelbrot.c | 51 +++++++++++++++++++++++++++++++++++++----------- src/quicksort.c | 15 ++++++++++++-- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/mandelbrot.c b/src/mandelbrot.c index 489ed19..946cf4e 100644 --- a/src/mandelbrot.c +++ b/src/mandelbrot.c @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -120,18 +121,46 @@ draw(void *closure, struct scheduler *s) // Sinon on recoupe le morceau int mid_x = (start_x + end_x) / 2; int mid_y = (start_y + end_y) / 2; + int rc; - int rc1 = sched_spawn( - draw, new_mandelbrot_args(image, start_x, start_y, mid_x, mid_y), - s); - int rc2 = sched_spawn( - draw, new_mandelbrot_args(image, mid_x, start_y, end_x, mid_y), s); - int rc3 = sched_spawn( - draw, new_mandelbrot_args(image, start_x, mid_y, mid_x, end_y), s); - int rc4 = sched_spawn( - draw, new_mandelbrot_args(image, mid_x, mid_y, end_x, end_y), s); + while((rc = sched_spawn( + draw, + new_mandelbrot_args(image, start_x, start_y, mid_x, mid_y), + s)) < 0) { + if(errno != EAGAIN) { + break; + } + } + assert(rc >= 0); - assert(rc1 >= 0 && rc2 >= 0 && rc3 >= 0 && rc4 >= 0); + while( + (rc = sched_spawn( + draw, new_mandelbrot_args(image, mid_x, start_y, end_x, mid_y), + s)) < 0) { + if(errno != EAGAIN) { + break; + } + } + assert(rc >= 0); + + while( + (rc = sched_spawn( + draw, new_mandelbrot_args(image, start_x, mid_y, mid_x, end_y), + s)) < 0) { + if(errno != EAGAIN) { + break; + } + } + assert(rc >= 0); + + while((rc = sched_spawn( + draw, new_mandelbrot_args(image, mid_x, mid_y, end_x, end_y), + s)) < 0) { + if(errno != EAGAIN) { + break; + } + } + assert(rc >= 0); } } @@ -154,7 +183,7 @@ benchmark_mandelbrot(int serial, int nthreads) int rc; int size = WIDTH * HEIGHT; - if(!(image = malloc(size * sizeof(unsigned int)))) { + if(!(image = malloc(WIDTH * HEIGHT * sizeof(unsigned int)))) { perror("Image allocation"); return 1; } diff --git a/src/quicksort.c b/src/quicksort.c index 9351cc8..d4701a8 100644 --- a/src/quicksort.c +++ b/src/quicksort.c @@ -2,6 +2,7 @@ #include "../includes/sched.h" #include +#include #include #include #include @@ -87,9 +88,19 @@ quicksort(void *closure, struct scheduler *s) } p = partition(a, lo, hi); - rc = sched_spawn(quicksort, new_args(a, lo, p), s); + + while((rc = sched_spawn(quicksort, new_args(a, lo, p), s)) < 0) { + if(errno != EAGAIN) { + break; + } + } assert(rc >= 0); - rc = sched_spawn(quicksort, new_args(a, p + 1, hi), s); + + while((rc = sched_spawn(quicksort, new_args(a, p + 1, hi), s)) < 0) { + if(errno != EAGAIN) { + break; + } + } assert(rc >= 0); } From 8704b182c3a3d6ec74f217154bb61736437ee0b4 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Sun, 5 May 2024 14:18:20 +0200 Subject: [PATCH 34/35] custom qlen as parameter --- includes/mandelbrot.h | 2 +- includes/quicksort.h | 2 +- src/main.c | 10 +++++++--- src/mandelbrot.c | 12 ++++++++---- src/quicksort.c | 9 ++++++--- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/includes/mandelbrot.h b/includes/mandelbrot.h index 724dfbf..543f69f 100644 --- a/includes/mandelbrot.h +++ b/includes/mandelbrot.h @@ -3,4 +3,4 @@ /* Lance le benchmark avec mandelbrot (TP10) * * Renvoie le temps d'exécution */ -double benchmark_mandelbrot(int, int); +double benchmark_mandelbrot(int, int, int); diff --git a/includes/quicksort.h b/includes/quicksort.h index 84e7a93..9f815d3 100644 --- a/includes/quicksort.h +++ b/includes/quicksort.h @@ -3,4 +3,4 @@ /* Lance le benchmark avec quicksort (fournis) * * Renvoie le temps d'exécution */ -double benchmark_quicksort(int, int); +double benchmark_quicksort(int, int, int); diff --git a/src/main.c b/src/main.c index dbcbd08..0fd48b7 100644 --- a/src/main.c +++ b/src/main.c @@ -11,13 +11,14 @@ main(int argc, char *argv[]) { int serial = 0; int nthreads = -1; + int qlen = -1; int quicksort = 0; int mandelbrot = 0; double delay; int opt; - while((opt = getopt(argc, argv, "qmst:")) != -1) { + while((opt = getopt(argc, argv, "qmst:n:")) != -1) { if(opt < 0) { goto usage; } @@ -35,6 +36,9 @@ main(int argc, char *argv[]) case 't': nthreads = atoi(optarg); break; + case 'n': + qlen = atoi(optarg); + break; default: goto usage; } @@ -44,9 +48,9 @@ main(int argc, char *argv[]) } if(quicksort) { - delay = benchmark_quicksort(serial, nthreads); + delay = benchmark_quicksort(serial, nthreads, qlen); } else if(mandelbrot) { - delay = benchmark_mandelbrot(serial, nthreads); + delay = benchmark_mandelbrot(serial, nthreads, qlen); } else { goto usage; } diff --git a/src/mandelbrot.c b/src/mandelbrot.c index 946cf4e..4833194 100644 --- a/src/mandelbrot.c +++ b/src/mandelbrot.c @@ -175,15 +175,19 @@ draw_serial(unsigned int *image) } double -benchmark_mandelbrot(int serial, int nthreads) +benchmark_mandelbrot(int serial, int nthreads, int qlen) { unsigned int *image; struct timespec begin, end; double delay; int rc; - int size = WIDTH * HEIGHT; + int n = WIDTH * HEIGHT; - if(!(image = malloc(WIDTH * HEIGHT * sizeof(unsigned int)))) { + if(qlen <= 0) { + qlen = n; + } + + if(!(image = malloc(n * sizeof(unsigned int)))) { perror("Image allocation"); return 1; } @@ -193,7 +197,7 @@ benchmark_mandelbrot(int serial, int nthreads) if(serial) { draw_serial(image); } else { - rc = sched_init(nthreads, size, draw, + rc = sched_init(nthreads, qlen, draw, new_mandelbrot_args(image, 0, 0, WIDTH, HEIGHT)); assert(rc >= 0); } diff --git a/src/quicksort.c b/src/quicksort.c index d4701a8..b996489 100644 --- a/src/quicksort.c +++ b/src/quicksort.c @@ -105,7 +105,7 @@ quicksort(void *closure, struct scheduler *s) } double -benchmark_quicksort(int serial, int nthreads) +benchmark_quicksort(int serial, int nthreads, int qlen) { int *a; struct timespec begin, end; @@ -113,6 +113,10 @@ benchmark_quicksort(int serial, int nthreads) int rc; int n = 10 * 1024 * 1024; + if(qlen <= 0) { + qlen = (n + 127) / 128; + } + a = malloc(n * sizeof(int)); unsigned long long s = 0; @@ -126,8 +130,7 @@ benchmark_quicksort(int serial, int nthreads) if(serial) { quicksort_serial(a, 0, n - 1); } else { - rc = sched_init(nthreads, (n + 127) / 128, quicksort, - new_args(a, 0, n - 1)); + rc = sched_init(nthreads, qlen, quicksort, new_args(a, 0, n - 1)); assert(rc >= 0); } From 3d3517acd5d2d66dd8804ff98df0f39b46e9d6c6 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Sun, 5 May 2024 14:21:48 +0200 Subject: [PATCH 35/35] new parameter --- README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README b/README index c3eaad6..6143ae6 100644 --- a/README +++ b/README @@ -14,6 +14,8 @@ Paramètres disponibles : * -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. +* -n x : où `x` est le nombre minimum de tâches simultanées supporter + par l'ordonnanceur * -s : n'utilises pas d'ordonnanceur Exemple : quicksort en utilisant tous les cœurs disponibles