Kompilering: `javac *.java` Kjøring: `java Main ` # Eksempelutskrift I filen output.txt finner du et eksempel på å kjøre `java Main 2000000000`. # Hvordan jeg har parallellisert ## Sil Silen har jeg parallellisert ved å først generere de sqrt(n) første primtallene sekvensielt, og så lager jeg n tråder som hver får en kopi av det arrayet som har løst de sqrt(n) første tallene. Hver tråd krysser av en del av tallene som ikke primtall. Når alle trådene er ferdige, slår jeg sammen arrayene til de forskjellige trådene ved å ORe hver byte i hvert array, slik at bare de tallene som ingen har markert som ikke primtall blir igjen. Jeg bruker OR istedenfor AND fordi jeg lar 0 bety at tallet er primtall og 1 bety at det ikke er primtall, fordi det gjør at jeg slipper å gå igjennom hele arrayet og sette hver byte til 11111111 når jeg oppretter silen, siden et array av tall i Java starter som et array av 0. ## Faktorisering Hver tråd får en del av primtallene opp til sqrt(n). Tråden går igjennom disse primtallene, og når den finner et primtall som n kan deles på, gir den det tallet til en monitor, som legger det til i en liste over faktorer og deler n på primtallet. Alle trådene må deretter oppdatere hvilket tall de jobber med og begynne på nytt. Når trådene har kommet til et tall som er større enn sqrt(n) uten å finne faktorer, stopper tråden. Når alle trådene har stoppet, vet monitoren at den er ferdig. Hvis tallet monitoren har kommet frem til så langt etter å ha latt trådene faktorisere, er større enn sqrt(n), legges dette tallet til listen faktorer, siden vi da vet at det er en faktor. Måten primtallene fordeles på, er at hver tråd tar hvert n-te primtall, hvor n er antall tråder, og hver tråd gis en unik startposisjon. Hvis det for eksempel er 2 tråder, vil tråd 1 ta primtall 1(3), 3(7), 5(13), etc, og tråd 2 vil ta primtall 2(5), 4(11), 6(17), etc. (I trådene later jeg som at alle primtall er oddetall og at 3 er det første primtallet, og lar monitoren ta seg av 2, fordi det gjør ting mye lettere.) Legg også merke til at jeg gjenbruker trådene mine, fordi det hadde tatt en del tid å lage 400 tråder, 4 for hver faktorisering. Noe jeg kunne ha gjort, som ville ha gjort koden min mye raskere, er å lage et array av primtall, istedenfor å bare gå igjennom oddetall og spørre silen om det er et primtall. Dette kom jeg på for sent til å kunne prøve det ut. # Tider CPU: quad core Intel Xeon E31225 @ 3.1 GHz (ingen hyperthreading) 2 000 000 000: * Erastothenes' Sil sekvensielt: 9.82s * Erastothenes' Sil parallelt: 6.77s (1.45x speedup) * Faktorisering sekvensielt: 1176.19s * Faktorisering parallelt: 356.50s (3.3x speedup) 200 000 000: * Erastothenes' Sil sekvensielt: 829.98ms * Erastothenes' Sil parallelt: 618.72ms (1.34x speedup) * Faktorisering sekvensielt: 115.10s * Faktorisering parallelt: 37.20s (3.09x speedup) 20 000 000: * Erastothenes' Sil sekvensielt: 68.11ms * Erastothenes' Sil parallelt: 41.41ms (1.64x speedup) * Faktorisering sekvensielt: 13.82s * Faktorisering parallelt: 4.31s (3.21x speedup) 2 000 000: * Erastothenes' Sil sekvensielt: 15.67ms * Erastothenes' Sil parallelt: 9.58ms (1.64x speedup) * Faktorisering sekvensielt: 1.17s * Faktorisering parallelt: 534.75s (2.18x speedup)