You are on page 1of 16

Τµήµα Μηχανικών Η/Υ και Πληροφορικής

Πανεπιστήµιο Πατρών

Παράλληλη Επεξεργασία
΄Ασκηση Εξαµήνου

Πάτρα, 2013

∆ουράτσος Ιωάννης 4978


douratsos@ceid.upatras.gr

Κεραµάς Ιωάννης 5000


keramas@ceid.upatras.gr

Τζανέτου Ιωάννα 5084


tzanetou@ceid.upatras.gr
1 Παραδοχές
Κατά την προσπάθεια εκπόνησης της εργασίας ήρθαµε αντιµέτωποι µε ένα σηµαντικό πρόβληµα. Το εργαλειο
Scalasca δε κατάφερνε να συνεργαστει σωστά µε το εργαλειο papi κάτι που µας οδήγησε στο να µη µπορούµε να
χειριστούµε τους performance counters του τελευταίου. Συνεπώς η ανάλυση που κάναµε ϐασίζεται στους χρόνους
εκτέλεσης συναρτήσεων που µας ανέφερε το scalasca καθώς και σε αναλύση του κώδικα από εµάς. ∆υστυχώς δεν
ήταν δυνατόν να ερευνήσουµε cache misses και tlb misses.

2 Ανάλυση σειριακού κώδικα


Πριν προχωρήσουµε στην παραλληλοποίηση του προγράµµατος καλούµαστε να εκτελέσουµε το εργαλείο Scalasca
και να εντοπίσουµε τη σηµείο του κώδικα στο οποίο καταναλώνεται περισσότερος χρόνος στο πρόγραµµά µας . Από την
εκτέλεση του προγράµµατος παίρνουµε τα εξής αποτελέσµατα :

Παρατηρούµε ότι η συνάρτηση dist και κατά δεύτερο λόγο η pgain καταναλώνουν τον περισσότερο χρόνο εκτέλεσης
στο πρόγραµµά µας. Συνεπώς καταλήγουµε πως πρέπει να παραλληλοποιήσουµε τα συγκεκριµένα τµήµατα του κώδικα
για να έχουµε αύξηση των χρονικών επιδόσεων.
3 Παραλληλοποίηση µε χρήση OpenMP
3.1 Συνάρτηση dist
Ξεκινώντας µε τη συνάρτηση dist αρχικά επιχειρούµε να την παραλληλοποιήσουµε χρησιµοποιώντας το πρότυπο
OpenMP και συγκεκριµένα την οδηγία
]pragma omp for reduction(+:result)
η οποία κάνει διαµοιρασµό εργασίας σε νήµατα που διαθέτουµε, ο αριθµός των οποίων είναι προκαθορισµένος από τη
µεταβλητή περιβάλλοντος OMP_NUM_THREADS. Το reduction εξασφαλίζει ότι η τελική τιµή της result ϑα είναι το άθροισµα
των µερικών αθροισµάτων της τοπικής µεταβλητής result που έχει το κάθε νήµα, διασφαλίζοντας έτσι την ορθότητα του
αποτελέσµατος.
Εκτελώντας τον τροποποιηµένο κώδικα παρατηρούµε ότι το πρόγραµµα παρουσιάζει χρονοκαθυστέρηση σε σχέση
µε το αρχικό και άρα επιλέγουµε τελικά να µη κάνουµε τη συγκεκριµένη αλλαγή. Ο λόγος για των οποίο συµβάινει αυτό
είναι γιατί ο ϐρόχος στον οποίο εφαρµόζουµε παραλληλοποίηση είναι αρκετά µικρός και ο ϕόρτος εργασίας σε κάθε
επανάληψη είναι επίσης αρκετά µικρός (τέσσερις αριθµητικές πράξεις) ώστε η δηµιουργία νηµάτων να επιβαρύνει τελικά
την εκτέλεσή του, αφού για να γίνει ο καταµερισµός τους πρέπει να γίνουν οι κατάλληλες αρχικοποιήσεις σε κάθε νήµα.

3.2 Συνάρτηση pgain


Εφόσον δε καταφέραµε να κάνουµε την παραλληλοποίηση στη συνάρτηση dist , καταλήγουµε να παραλληλοποι-
ήσουµε τη συνάρτηση pgain καθώς εκείνη καλεί την dist και επίσης είναι η δεύτερη χρονικά κοστοβόρα συνάρτηση
σύµφωνα µε το Scalasca.
Αναλυτικότερα, η pgain σε ένα ϐρόγχο επανάληψης for υπολογίζει µέσω της dist την ευκλείδια απόσταση µεταξύ δύο
διανυσµάτων και ανάλογα µε το αποτέλεσµα αποφασίζει πως ϑα δράσει. Παρατηρούµε ότι ο ϐρόχος αυτός είναι δυνατόν
να παραλληλοποιηθεί καθώς δεν έχουµε µεταβλητές που τροποποιούνται ταυτόχρονα και συνεπώς δεν παρατηρούνται
συνθήκες ανταγωνισµού αφού τα νήµατα είτε ϑα δουλεύουν σε µεταβλητές τοπικής εµβέλειας που αρχικοποιούνται
µέσα στην ίδια τη for είτε σε διαφορετικά κοµµάτια ενός κοινού πίνακα. Μοναδική εξαίρεση αποτελεί η µεταβλητή
cost_of_opening_x στην οποία και αθροίζονται όλες οι επαναλήψεις.Συνεπώς παραλληλοποιούµε το ϐρόχο κατάλληλα µε
τη χρήση της
] pragma omp for reduction(+:cost_of_opening_x) schedule(guided,5)
αφού έχουµε δηλώσει το κοµµάτι αυτό ως παράλληλη περιοχή µε τη χρήση της
] pragma omp parallel.
Σε αυτό τον ϐρόγχο αφού δεν έχουµε δηλώσει κάτι ϱητά όλες οι µεταβλητές γίνονται διαµοιραζόµενες στα νήµατα , εκτός
από την cost_of_opening_x η οποία είναι ιδιωτική για κάθε νήµα και η τελική της τιµή είναι το άθροισµα των επιµέρους
αθροισµάτων του κάθε νήµατος. Τέλος η επιλογή schedule(guided,5) είναι η επιλογή χρονοπρογραµµατισµού που είχε
καλύτερα αποτελέσµατα για το πρόγραµµα µας, κάθώς τόσο η static όσο και τα διάφορα άλλα µεγέθη guided και
dynamic είχαν ως αποτέλεσµα πιο µεγάλους χρόνους.
Ακριβώς κάτω από τον παραπάνω ϐρόγχο υπάρχει άλλος ένας οπότε επεκτείνουµε την παράλληλη περιοχή µας για
να συµπεριλάβουµε και αυτόν. Για την παραλληλοποίηση του εφαρµόζουµε την εντολή
] pragma omp for reduction(+:number_of_centers_to_close) reduction(-:cost_of_opening_x) schedule(guided,5)
Πάλι όσες µεταβλητές δεν έχουν οριστεί γίνονται διαµοιραζόµενες µεταξύ των νηµάτων εκτός από την number_ of_
centers_ to_ close και την cost_ of_ opening_ x οι οποίες γίνονται τοπικές για κάθε νήµα και ενηµερώνονται µε τον
αντίστοιχο τελεστή που υπάρχει ως όρισµα µέσα στην reduction ώστε να εξασφαλίσουν τον υπολογισµό των σωστών
τιµών για τις αντίστοιχες µεταβλητές, όπως ακριβώς έχουµε ήδη περιγράψει νωριτερα.
Μέχρι τον επόµενο ϐρόγχο που ϑα παραλληλοποιήσουµε έχουµε εντολές που αφορούν λειτουργίες στην µνήµη
και συνεπώς πρέπει να εκτελεστούν από ένα µόνο νήµα, οπότε κλείνουµε τη παράλληλη περιοχή ακριβώς µετά το
πέρας του ϐρόγχου for. Μετά το πέρας των εντολών που αφορούν µνήµη, εχουµε ακόµα δύο ϐρόχους επανάληψης να
παραλληλοποιήσουµε συνεπώς τους τοποθετούµε σε µία παράλληλη περιοχή.
Στον πρώτο ϐρόγχο ϐάζουµε την εντολή

3
] pragma omp for nowait
΄Ολες οι µεταβλητές είναι διαµοιραζόµενες µεταξύ των νηµάτων αλλά αυτό δε µας προβληµατίζει γιατί τα νήµατα δουλε-
ύουν µε τοπικές µεταβλητές που υπάρχουν στο µπλοκ του ϐρόγχου. Τοποθετήσαµε το όρισµα nowait το οποίο δηλώνει ότι
δεν υπάρχει ϕράγµα στο τέλος του ϐρόγχου επανάληψης συνεπώς οποιδήποτε νήµα τελειώνει µπορεί να συνεχίσει στο
επόµενο τµήµα του κώδικα. Αυτό µας το επιτρέπει το γεγονός ότι στον επόµενο ϐρόγχο δεν επεξεργαζόµαστε δεδοµένα
που έχουν προκύψει από τον προηγούµενο ϐρόγχο. ∆ηλαδή οι δύο ϐρόγχοι είναι ανεξάρτητοι κάτι που σηµαίνει ότι ϑα
αν ένα νήµα τελειώσει πιο γρήγορα τη δουλειά του µπορούµε να του αναθέσουµε αµέσως νέα, αυξάνοντας έτσι την
απόδοση του προγράµµατος µας.
Τέλος, µε την εντολή

] pragma omp for

παραλληλοποιούµε το δεύτερο ϐρόγχο αφού κάθε επανάληψη δουλεύει σε διαφορετικό σηµείο των διαµοπιραζόµενων
µεταβλητών και συνεπώς δε χρειάζεται να προσθέσουµε εµείς κάποια επιπλέον παράµετρο ώστε να εξασφαλίσουµε τη
σωστή λειτουργία.
Με τη προσθήκη και αυτού του κώδικα, έχουµε παραλληλοποιήσει την πγαιν κατά το µέγιστο. Η προσθήκη παραπάνω
εντολών, (πχ σε κάποια άλλη πολύ µικρή από άποψη δουλειάς for) δεν είχε τα επιθυµητά αποτελέσµατα, αλλά αύξανε
το χρόνο εκτέλεσης. Το ίδιο συνέβη και κατά την προσπάθεια µας να παραλληλοποιήσουµε την αµέσως επόµενη από
άποψη χρόνου στο scalasca συνάρτηση, την pspeedy, στην οποία οποιαδήποτε προσπάθεια για προσθήκη νηµάτων είχε
ως αποτέλεσµα την αύξηση του χρόνου κάτι λογικό, αφού η pspeedy κατείχε ένα εξαιρετικά µικρό ποσοστό του χρόνου
εκτέλεσης του προγράµµατος και η προσθήκη νηµάτων όπως περιγράψαµε και στη dist οδήγησε στην καθυστέρηση της
εκτέλεσης της.

4 Παραλληλοποίηση µε χρήση εντολών SIMD


4.1 Συνάρτηση dist
Καθώς οι εντολές SIMD χρησιµοποιούνται για γρήγορη εκτέλεση αριθµητικών πράξεων µε περισσότερα από ένα
δεδοµένα τη ϕορά, το σωστότερο και πιο αποδοτικό ήταν να τις χρησιµοποιήσουµε στη συνάρτηση dist η οποία και παρόλο
που κατειχε το περισσότερο χρόνο της εκτέλεσης του κώδικα, αποτελούνταν µόνο από αριθµητικές πράξεις κάτι που µας
έκανε να περιµένουµε αρκετά καλή ϐελτίωση του χρόνου εκτελεσης της.
Για την υλοποίηση µε simd χρησιµοποιούµε τη δοµή v4sf η οποία ορίζει ένα vector που µπορεί να χωρέσει 4 αριθµούς
κινητής υποδιαστολής µεγέθους 32 bit ο καθένας. Επειδή αυτή είναι µια ειδική δοµή, δεν υποστηρίζει τους κλασσικούς
τελεστές αριθµητικών πράξεων, αλλά αντί για αυτό ϑα χρησιµοποιήσουµε built-in συναρτήσεις η οποίες χρησιµοποιούν
τη δυνατότητα των σύγχρονων επεξεργαστών να επεξεργάζονται 128 bit ανα ϕορά. Για αυτό το λόγο ο ϐρόχος µας ϑα
εκτελεστεί Ν/4 ϕορές, όπου Ν ο αρχικός αριθµός επαναλήψεων και σε κάθε επανάληψη αντιγράφουµε τα δεδοµένα που
ϑέλουµε να επεξεργαστούµε στις ειδικές αυτές δοµές, τις οποίες και χρησιµοποιούµε για να εκτελούµε τις αριθµητικές
µας πράξεις σε τετράδες δεδοµένων πολύ πιο γρήγορα. Η όλη αυτή διαδικασία ϑα έχει ως αποτέλεσµα τη παραγωγή
τεσσάρων µερικών αποτελεσµάτων, τα οποία και ϑα αθροίσουµε µεταξύ τους. Στο τέλος των επαναλήψεων µεριµνούµε
ώστε να επεξεργαστούµε και τα τελευταία δεδοµένα σε περίπτωση που η διαίρεση του Ν σε τετράδες άφησε κάποια
δεδοµένα εκτός ϐρογχου, κάτι που ϑα συµβαινει αν το Ν δεν είναι πολλαπλάσιο του τεσσερα. Τέλος, µεταφέρουµε το
αποτελέσµα σε µια µεταβλητή τύπου float ώστε να είναι συµβατή µε το υπόλοιπο πρόγραµµα .

5 Σύγκριση σειριακού µε παράλληλες εκδόσεις


Χρησιµοποιώντας τον κώδικα που παρατίθεται στο παράρτηµα, χρονοµετρήσαµε τις διάφορες εκδόσεις του προγράµ-
µατος. Τα αποτελέσµατα ϕαίνονται στους παρακάτω πίνακες, όπου η πρώτη γραµµή αντιπροσωπευει τις παραµέτρους
small , η δεύτερη τις medium και η τρίτη τις large ενώ οι στήλες αντιπροσωπεύουν τον αριθµό πυρήνων 1,2 ή 4 αντίστοιχα.
΄Ολοι οι χρόνοι είναι σε δευτερόλεπτα.

4
 ΄Εκδοση OpenMP -Ο0  ΄Εκδοση OpenMP -Ο3 
129.579 71.1904 47.8969 38.91 24.1717 22.2504
 534.363 282.665 147.648   152.482 86.6444 67.3398 
1912.47 1000.19 637.901 504.088 287.696 247.221

 ΄Εκδοση SIMD -Ο0  ΄Εκδοση SIMD -Ο3 


66.7324 37.383 30.0316 29.0697 20.6861 18.0501
 252.009 135.998 80.3152   109.137 74.2027 64.7666 
872.855 462.742 313.959 345.757 248.826 223.614

 Σειριακή έκδοση -Ο0  Σειριακή έκδοση -Ο3 


44.1317 44.4317 44.2117 128.831 128.831 128.831
 152.364 152.264 152.764   539.02 539.02 539.02 
503.325 503.025 502.325 1890.91 1890.91 1890.91

5
Για καλύτερη οπτικοποίηση των αποτελεσµάτων προχωρήσαµε στη δηµιουργία γραφηµάτων που δείχνουν τους
χρόνους εκτέλεσης

• Χρόνοι εκτέλεσης για µικρές παραµέτρους εισόδου

• Χρόνοι εκτέλεσης για µεσαίες παραµέτρους εισόδου

6
• Χρόνοι εκτέλεσης για µεγάλες παραµέτρους εισόδου

Ενώ παρακάτω ϕαίνεται και το ποσοστιαίο κέρδος που είχε κάθε έκδοση µε την αύξηση των χρησιµοποιούµενων
νηµάτων :
• Ποσοστιαία αύξηση απόδοσης για µικρές παραµέτρους εισόδου

7
• Ποσοστιαία αύξηση απόδοσης για µεσαίες παραµέτρους εισόδου

• Ποσοστιαία αύξηση απόδοσης για µεγάλες παραµέτρους εισόδου

8
Παρατηρούµε ότι όταν ο compiler χρησιµοποιεί την παράµετρο -Ο3 , οπότε και κάνει ϐελτιστοποιήσεις στον κώδικα
κατά το compilation, η αύξηση της απόδοσης είναι µικρότερη. Αυτό οφείλεται στο ότι ο compiler ϑα ενώσει κάποιους
ϐρόγχους for και ϑα κάνει και άλλες λειτουργίες οι οποίες ϱίχνουν αρκετά το χρόνο εκτέλεσης, αφήνοντας µας ως
αποτέλεσµα µικρότερο χώρο για ϐελτίωση του. Στις εκδόσεις στις οποίες ο compiler δε πραγµατοποιεί ϐελτιστοποιήσεις
παρατηρειται σηµαντικά µεγαλύτερο κέρδος. Συγκεκριµένα, ενώ στις -Ο3 τόσο µε 2 όσο και µε 4 νήµατα είχαµε περίπου
100% αύξηση, στις -Ο0 έχουµε έως και 250% αύξηση για την έκδοση µε openmp ενώ όταν χρησιµοποιήσουµε και εντολές
simd η αύξηση εκτινάσεται πάνω από 500% . Παρατηρούµε ότι η εισαγωγή εντολών simd αυξάνει πάρα πολύ την απόδοση
του προγράµµατος µας. Και πάλι όµως, δεν επιτυγχάνουµε τη ϑεωρητική αύξηση που λέει πως εφόσον εκτελούµε τις
αριθµητικές πράξεις σε τετράδες δεδοµένων έπρεπε να περιµένουµε τετραπλασιασµό της απόδοσης. Αυτό συµβαίνει
για διάφορους λόγους και πιθανότατα οφείλεται στην αρχιτεκτονική των σύγχρονων επεξεργαστών η οποία δεν µας
επιτρέπει να επιτύχουµε το κέρδος που µας δίνει η ϑεωρητική υλοποίηση.

9
6 Παράρτηµα
6.1 Αναπαράσταση Αποτελεσµάτων
Για την αναπαράσταση των χρονικών αποτελεσµάτων που καταγράψαµε, δηµιουργήθηκε ο παρακάτω κώδικας σε
matlab:

1 seqO0 = [128.831221,128.831221,128.831221 ;...


2 539.020116,539.020116,539.020116; ...
3 1890.907759,1890.907759,1890.907759];
4 ompO0 = [129.579321,71.190421,47.896904 ;...
5 534.363034,282.665243,147.647928; ...
6 1912.465560,1000.194080,637.901400];
7 ompsimdO0 = [66.732428,37.383013,30.031565; ...
8 252.009082,135.998392,80.315214; ...
9 872.855030,462.741622,313.959174];
10

11 seqO3 = [44.131685,44.431685,44.211685 ;...


12 152.363564,152.263564,152.763564; ...
13 503.325094,503.025094,502.325094];
14 ompO3 = [38.909973,24.171704,22.250449 ;...
15 152.481637,86.644360,67.339822; ...
16 504.088029,287.696121,247.220563];
17 ompsimdO3 = [29.069744,20.686058,18.050103;...
18 109.136970,74.202728,64.766644; ...
19 345.756739,248.825814,223.613715];
20

21 threads = [1,2,4];
22 max_axis = [200 800 2000];
23 names = [’small’ ’medium’ ’large’];
24 f o r k=1:3
25 f i g u r e (k);
26 s e t (0,’DefaultAxesLineStyleOrder’,’-|-.|--|:’)
27

28 plot1 = p l o t (threads,seqO0(k,:),...
29 threads,ompO0(k,:),...
30 threads,ompsimdO0(k,:),...
31 threads,seqO3(k,:),...
32 threads,ompO3(k,:),...
33 threads,ompsimdO3(k,:),...
34 ’MarkerSize’,20,’Marker’,’.’,...
35 ’LineWidth’,1,...
36 ’LineStyle’,’--’);
37 s e t (plot1(1),’MarkerFaceColor’,’auto’,’DisplayName’,’seq -O0’);
38 s e t (plot1(2),’DisplayName’,’omp with simd -O0’);
39 s e t (plot1(3),’MarkerFaceColor’,’auto’,’DisplayName’,’seq -03’);
40 s e t (plot1(4),’DisplayName’,’omp -O3’);
41 s e t (plot1(5),’DisplayName’,’omp with simd -O3’);
42 s e t (plot1(6),’MarkerFaceColor’,’auto’,’DisplayName’,’omp -O0’);
43 a x i s ([0 5 0 max_axis(k)]);
44 y l a b e l ( ’Time’ );
45 x l a b e l ( ’Threads’ );
46

47 l e g e n d (’seq -O0’,’omp -O0’,’simd -O0’,’seq -03’,’omp -O3’,’simd -O3’ );


48 t i t l e (’Scaling of omp and simd versions on small numbers’);

10
49

50 f i g u r e (3+k);
51 s e t (0,’DefaultAxesLineStyleOrder’,’-|-.|--|:’)
52

53 plot2 = p l o t (threads,perc_gain(seqO0(1,:),seqO0(1,:)),...
54 threads,perc_gain(ompO0(1,:),seqO0(1,:)),...
55 threads,perc_gain(ompsimdO0(1,:),seqO0(1,:)),...
56 threads,perc_gain(seqO3(1,:),seqO3(1,:)),...
57 threads,perc_gain(ompO3(1,:),seqO3(1,:)),...
58 threads,perc_gain(ompsimdO3(1,:),seqO3(1,:)),...
59 ’MarkerSize’,20,’Marker’,’.’,...
60 ’LineWidth’,1,...
61 ’LineStyle’,’--’);
62 s e t (plot2(1),’MarkerFaceColor’,’auto’,’DisplayName’,’seq -O0’);
63 s e t (plot2(2),’DisplayName’,’omp with simd -O0’);
64 s e t (plot2(3),’MarkerFaceColor’,’auto’,’DisplayName’,’seq -03’);
65 s e t (plot2(4),’DisplayName’,’omp -O3’);
66 s e t (plot2(5),’DisplayName’,’omp with simd -O3’);
67 s e t (plot2(6),’MarkerFaceColor’,’auto’,’DisplayName’,’omp -O0’);
68 a x i s ([0 5 0 500]);
69 y l a b e l ( ’% increase in execusion speed’ );
70 x l a b e l ( ’Threads (s) ’ );
71

72 l e g e n d (’seq -O0’,’omp -O0’,’simd -O0’,’seq -03’,’omp -O3’,’simd -O3’ );


73 t i t l e (’Scaling of omp and simd versions on small numbers’);
74

75

76 end

Η συνάρτηση που υπολογίζει την ποσοστιαία αύξηση απόδοσης :

1 f u n c t i o n [R] = perc_gain(X1,X2)
2 R = abs (X1-X2)./ X1;
3 R = R *100;
4 end

11
6.2 Bash Script
Για το compiling καθώς και την εκτέλεση του προγράµµατος χρησιµοποιήθηκε το παρακάτω bash script το οποίο εκτελεί
την τελευταία έκδοση του κώδικα µε τα ορίσµατα της επιλογής µας, τόσο για τη σειριακή όσο και για τις παράλληλες
εκδοχές του κώδικα, ενώ τα αποτελέσµατα που εξάγονται αντιγράφονται στο αρχείο report.txt.

1 #!/bin/bash
2 i f [[ -f diff_results.txt ]]; t h e n
3 echo ’deleting previous file!’
4 rm diff_results.txt
5

6 fi
7 i f [[ -f output_small_O0.txt ]]; t h e n
8 echo ’deleting previous temporary files!’
9 rm output_small_*.txt
10

11 fi
12 i f [[ -f output_medium_O0.txt ]]; t h e n
13 echo ’deleting previous temporary files!’
14 rm output_medium_*.txt
15

16 fi
17 i f [[ -f output_large_O0.txt ]]; t h e n
18 echo ’deleting previous temporary files!’
19 rm output_large_*.txt
20

21 fi
22 i f [[ -f report.txt ]]; t h e n
23 rm report.txt
24

25 fi
26 echo ’compiling single threaded with O3....’
27 g++ -O3 -Wall -Wextra -o streamcluster_O3 streamcluster.cpp | grep error
28 echo ’compiling single threaded with O0....’
29 g++ -O0 -Wall -Wextra -o streamcluster_O0 streamcluster.cpp | grep error
30 echo ’compiling omp version with O3....’
31 g++ -O3 -fopenmp -Wall -Wextra -o streamcluster_omp_O3 streamcluster_omp.cpp | grep error
32 echo ’compiling omp version with O0....’
33 g++ -O0 -fopenmp -Wall -Wextra -o streamcluster_omp_O0 streamcluster_omp.cpp | grep error
34 echo ’compiling omp+simd version with O3....’
35 g++ -O3 -fopenmp -msse -Wall -Wextra -o streamcluster_omp_simd_O3 \
36 streamcluster_omp_simd.cpp | grep error
37 echo ’compiling omp+simd version with O0....’
38 g++ -O0 -fopenmp -msse -Wall -Wextra -o streamcluster_omp_simd_O0 \
39 streamcluster_omp_simd.cpp | grep error
40 echo ’’
41 echo ’’
42 echo ’’
43 echo ’’
44

45 while true
46 do
47

48 r e a d -p ’Choose your size (1-2-3)-(4-5-6)!Use 0 to e x i t :’ choice


49 case "$choice" in
50 1)

12
51 echo ’normal numbers’ >> report.txt
52 echo ’SMALL’ | tee -a report.txt
53 echo ’running sequential program with -O0’ | tee -a report.txt
54 ./streamcluster_O0 10 20 32 4096 4096 1000 none output_small_O0.txt | tee -a report.txt
55 echo ’running parallel program with -O0: ’ | tee -a report.txt
56 ./streamcluster_omp_O0 10 20 32 4096 4096 1000 none output_small_omp_O0.txt \
57 | tee -a report.txt
58 echo ’running parallel program +simd commands with -O0: ’ | tee -a report.txt
59 ./streamcluster_omp_simd_O0 10 20 32 4096 4096 1000 none output_small_omp_simd_O0.txt \
60 | tee -a report.txt
61 echo ’running sequential program with -O3’ | tee -a report.txt
62 ./streamcluster_O3 10 20 32 4096 4096 1000 none output_small_O3.txt \
63 | tee -a report.txt
64 echo ’running parallel program with -O3: ’ | tee -a report.txt
65 ./streamcluster_omp_O3 10 20 32 4096 4096 1000 none output_small_omp_O3.txt \
66 | tee -a report.txt
67 echo ’running parallel program +simd commands with -O3: ’ | tee -a report.txt
68 ./streamcluster_omp_simd_O3 10 20 32 4096 4096 1000 none output_small_omp_simd_O3.txt \
69 | tee -a report.txt
70

71 diff output_small_O0.txt output_small_omp_O0.txt > diff_results.txt


72 diff output_small_O0.txt output_small_omp_simd_O0.txt >> diff_results.txt
73 diff output_small_O3.txt output_small_omp_O3.txt >> diff_results.txt
74 diff output_small_O3.txt output_small_omp_simd_O3.txt >> diff_results.txt
75

76 ;;
77

78 2)
79 echo ’normal numbers’ >> report.txt
80 echo ’MEDIUM’ | tee -a report.txt
81 echo ’running sequential program with -O0’ | tee -a report.txt
82 ./streamcluster_O0 10 20 64 8192 8192 1000 none output_medium_O0.txt | tee -a report.txt
83 echo ’running parallel program with -O0: ’ | tee -a report.txt
84 ./streamcluster_omp_O0 10 20 64 8192 8192 1000 none output_medium_omp_O0.txt \
85 | tee -a report.txt
86 echo ’running parallel program +simd commands with -O0: ’ | tee -a report.txt
87 ./streamcluster_omp_simd_O0 10 20 64 8192 8192 1000 none output_medium_omp_simd_O0.txt \
88 | tee -a report.txt
89 echo ’running sequential program with -O3’ | tee -a report.txt
90 ./streamcluster_O3 10 20 64 8192 8192 1000 none output_medium_O3.txt \
91 | tee -a report.txt
92 echo ’running parallel program with -O3: ’ | tee -a report.txt
93 ./streamcluster_omp_O3 10 20 64 8192 8192 1000 none output_medium_omp_O3.txt \
94 | tee -a report.txt
95 echo ’running parallel program +simd commands with -O3: ’ | tee -a report.txt
96 ./streamcluster_omp_simd_O3 10 20 64 8192 8192 1000 none output_medium_omp_simd_O3.txt \
97 | tee -a report.txt
98

99 diff output_medium_O0.txt output_medium_omp_O0.txt > diff_results.txt


100 diff output_medium_O0.txt output_medium_omp_simd_O0.txt >> diff_results.txt
101 diff output_medium_O3.txt output_medium_omp_O3.txt >> diff_results.txt
102 diff output_medium_O3.txt output_medium_omp_simd_O3.txt >> diff_results.txt
103

104 ;;
105

106 3)

13
107 echo ’normal numbers’ >> report.txt
108 echo ’LARGE’ | tee -a report.txt
109 echo ’running sequential program with -O0’ | tee -a report.txt
110 ./streamcluster_O0 10 20 128 16384 16384 1000 none output_large_O0.txt \
111 | tee -a report.txt
112 echo ’running parallel program with -O0: ’ | tee -a report.txt
113 ./streamcluster_omp_O0 10 20 128 16384 16384 1000 none output_large_omp_O0.txt \
114 | tee -a report.txt
115 echo ’running parallel program +simd commands with -O0: ’ | tee -a report.txt
116 ./streamcluster_omp_simd_O0 10 20 128 16384 16384 1000 none output_large_omp_simd_O0.txt\
117 | tee -a report.txt
118 echo ’running sequential program with -O3’ | tee -a report.txt
119 ./streamcluster_O3 10 20 128 16384 16384 1000 none output_large_O3.txt \
120 | tee -a report.txt
121 echo ’running parallel program with -O3: ’ | tee -a report.txt
122 ./streamcluster_omp_O3 10 20 128 16384 16384 1000 none output_large_omp_O3.txt \
123 | tee -a report.txt
124 echo ’running parallel program +simd commands with -O3: ’ \
125 | tee -a report.txt
126 ./streamcluster_omp_simd_O3 10 20 128 16384 16384 1000 none output_large_omp_simd_O3.txt \
127 | tee -a report.txt
128

129 diff output_large_O0.txt output_large_omp_O0.txt > diff_results.txt


130 diff output_large_O0.txt output_large_omp_simd_O0.txt >> diff_results.txt
131 diff output_large_O3.txt output_large_omp_O3.txt >> diff_results.txt
132 diff output_large_O3.txt output_large_omp_simd_O3.txt >> diff_results.txt
133

134 ;;
135

136 4)
137 echo ’big numbers’ >> report.txt
138 echo ’SMALL’ | tee -a report.txt
139 echo ’running sequential program with -O0’ | tee -a report.txt
140 ./streamcluster_O0 10 20 256 32768 32768 1000 none output_small_O0.txt \
141 | tee -a report.txt
142 echo ’running parallel program with -O0: ’ | tee -a report.txt
143 ./streamcluster_omp_O0 10 20 256 32768 32768 1000 none output_small_omp_O0.txt \
144 | tee -a report.txt
145 echo ’running parallel program +simd commands with -O0:’| tee -a report.txt
146 ./streamcluster_omp_simd_O0 10 20 256 32768 32768 1000 none output_small_omp_simd_O0.txt \
147 | tee -a report.txt
148 echo ’running sequential program with -O3’| tee -a report.txt
149 ./streamcluster_O3 10 20 256 32768 32768 1000 none output_small_O3.txt \
150 | tee -a report.txt
151 echo ’running parallel program with -O3: ’ | tee -a report.txt
152 ./streamcluster_omp_O3 10 20 256 32768 32768 1000 none output_small_omp_O3.txt \
153 | tee -a report.txt
154 echo ’running parallel program +simd commands with -O3: ’ | tee -a report.txt
155 ./streamcluster_omp_simd_O3 10 20 256 32768 32768 1000 none output_small_omp_simd_O3.txt \
156 | tee -a report.txt
157

158 diff output_small_O0.txt output_small_omp_O0.txt > diff_results.txt


159 diff output_small_O0.txt output_small_omp_simd_O0.txt >> diff_results.txt
160 diff output_small_O3.txt output_small_omp_O3.txt >> diff_results.txt
161 diff output_small_O3.txt output_small_omp_simd_O3.txt >> diff_results.txt
162

14
163 ;;
164

165 5)
166 echo ’big numbers’ >> report.txt
167 echo ’MEDIUM’ | tee -a report.txt
168 echo ’running sequential program with -O0’ | tee -a report.txt
169 ./streamcluster_O0 10 20 512 65536 65536 1000 none output_medium_O0.txt \
170 | tee -a report.txt
171 echo ’running parallel program with -O0: ’ | tee -a report.txt
172 ./streamcluster_omp_O0 10 20 512 65536 65536 1000 none output_medium_omp_O0.txt \
173 | tee -a report.txt
174 echo ’running parallel program +simd commands with -O0: ’ | tee -a report.txt
175 ./streamcluster_omp_simd_O0 10 20 512 65536 65536 1000 none output_medium_omp_simd_O0.txt \
176 | tee -a report.txt
177 echo ’running sequential program with -O3’ | tee -a report.txt
178 ./streamcluster_O3 10 20 512 65536 65536 1000 none output_medium_O3.txt
179 tee -a report.txt
180 echo ’running parallel program with -O3: ’ | tee -a report.txt
181 ./streamcluster_omp_O3 10 20 512 65536 65536 1000 none output_medium_omp_O3.txt
182 tee -a report.txt
183 echo ’running parallel program +simd commands with -O3: ’ | tee -a report.txt
184 ./streamcluster_omp_simd_O3 10 20 512 65536 65536 1000 none output_medium_omp_simd_O3.txt
185 tee -a report.txt
186

187 diff output_medium_O0.txt output_medium_omp_O0.txt > diff_results.txt


188 diff output_medium_O0.txt output_medium_omp_simd_O0.txt >> diff_results.txt
189 diff output_medium_O3.txt output_medium_omp_O3.txt >> diff_results.txt
190 diff output_medium_O3.txt output_medium_omp_simd_O3.txt >> diff_results.txt
191

192 ;;
193

194 6)
195 echo ’big numbers’ >> report.txt
196 echo ’LARGE’ | tee -a report.txt
197 echo ’running sequential program with -O0’ | tee -a report.txt
198 ./streamcluster_O0 10 20 1024 131072 131072 1000 none output_large_O0.txt
199 tee -a report.txt
200 echo ’running parallel program with -O0: ’ | tee -a report.txt
201 ./streamcluster_omp_O0 10 20 1024 131072 131072 1000 none output_large_omp_O0.txt
202 tee -a report.txt
203 echo ’running parallel program +simd commands with -O0: ’ | tee -a report.txt
204 ./streamcluster_omp_simd_O0 10 20 1024 131072 131072 1000 none output_large_omp_simd_O0.txt \
205 | tee -a report.txt
206 echo ’running sequential program with -O3’ | tee -a report.txt
207 ./streamcluster_O3 10 20 1024 131072 131072 1000 none output_large_O3.txt \
208 | tee -a report.txt
209 echo ’running parallel program with -O3: ’ | tee -a report.txt
210 ./streamcluster_omp_O3 10 20 1024 131072 131072 1000 none output_large_omp_O3.txt \
211 | tee -a report.txt
212 echo ’running parallel program +simd commands with -O3: ’ | tee -a report.txt
213 ./streamcluster_omp_simd_O3 10 20 1024 131072 131072 1000 none output_large_omp_simd_O3.txt \
214 | tee -a report.txt
215

216 diff output_large_O0.txt output_large_omp_O0.txt > diff_results.txt


217 diff output_large_O0.txt output_large_omp_simd_O0.txt >> diff_results.txt
218 diff output_large_O3.txt output_large_omp_O3.txt >> diff_results.txt

15
219 diff output_large_O3.txt output_large_omp_simd_O3.txt >> diff_results.txt
220

221 ;;
222

223 0)
224 exit
225 ;;
226 *)
227 echo ’invalid choice’
228 ;;
229 esac
230

231 i f [[ -f diff_results.txt ]]; t h e n


232 actualsize=$(du -b diff_results.txt | cut -f 1)
233

234 i f (( actualsize < 1 )) ; t h e n


235

236 echo ’The results from both programs are the same.’;
237 else
238 echo ’Abort ship!’
239 fi
240

241 fi
242

243

244 done

16

You might also like