Αρχική σελίδα Παράλληλης Επεξεργασίας
English version (Αγγλική έκδοση)
Ταξινόμηση σε Linear array
1) Θεωρητική παρουσίαση του αλγόριθμου
Ας θεωρήσουμε ότι έχουμε ένα linear array με Ν επεξεργαστικές μονάδες. Η είσοδος και η έξοδος των δεδομένων γίνεται σε κάθε επεξεργαστική μονάδα.(για άλλου είδους είσοδο-έξοδο υπάρχουν διαφορετικοί αλγόριθμοι).
Ο αλγόριθμος θεωρεί ότι το Ν είναι άρτιος αριθμός. Οι MCUs αριθμούνται από το 1 μέχρι το Ν. Η διαδικασία χωρίζεται σε δύο βήματα.
- Στο πρώτο βήμα, οι μονές MCUs συγκρίνουν τα δεδομένα τους με τα δεδομένα της MCU που βρίσκεται στα δεξιά τους (η MCU1 με την MCU2, η MCU3 με την MCU4, και λοιπά). Αν οι τιμές δεν βρίσκονται σε σωστή διάταξη, αλλάζουν θέση μεταξύ τους.
- Στο δεύτερο βήμα οι ζυγές MCUs συγκρίνουν και ανταλλάσσουν τις τιμές τους με τις τιμές των MCU που βρίσκονται στα δεξιά τους (η MCU2 με την MCU3, και λοιπά).
Η διαδικασία επαναλαμβάνεται Ν/2 φορές.
Το παρακάτω σχήμα δείχνει παραστατικά την διαδικασία (για Ν=8).
Περισσότερες λεπτομέρειες σχετικά με την ορθότητα και την απόδοση του αλγορίθμου βρίσκονται στο βιβλίο του F.T.Leighton.
Η υλοποίηση του αλγόριθμου γίνεται με οκτώ (8) μονάδες επεξεργασίας (Μ.Ε.)
2) Δίκτυο διασύνδεσης και Ι/Ο
Η υλοποίηση γίνεται σε "Parallel PIC" (Revision 1.0).
Κάθε μονάδα επεξεργασίας πρέπει να διαβάζει τα δεδομένα από κάποια πόρτα που έχει ελεύθερη. Στο συγκεκριμένο παράδειγμα η είσοδος έχει εύρος μόνο 2 Bits και υλοποιείται μέσω των σημάτων PortA(0,1). Αντίστοιχα η έξοδος βγαίνει στα σήματα PortA(3,4).
Κάθε MCU χρησιμοποιεί ένα (1) UART. Ο πομπός αντιστοιχίζεται στο RP15 για την επικοινωνία με την αριστερή MCU, και με το RP13 για την επικοινωνία με την δεξιά MCU. Ο δέκτης αντιστοιχίζεται με το RP14 για την επικοινωνία με την αριστερή MCU, και με το RP12 για την επικοινωνία με την δεξιά MCU. Το δίκτυο διασύνδεσης δημιουργείται συνδέοντας το RP13 από κάθε MCU με το RP14 από την MCU στα δεξιά, και το RP12 από κάθε MCU με το RP15 από την MCU δεξιά.
Μια φωτογραφία με την πλακέτα (Revision 1.0) βρίσκεται εδώ. Η πλακέτα προς τα δεξιά παρέχει τα 8 σήματα εισόδου των 2-bits και απεικονίζει τα 8 σήματα εξόδου (των 2 bits βέβαια).
3) Υλοποίηση με ψευδοκώδικα
Κάθε ένα από τα δύο βήματα που περιγράφηκαν στην θεωρητική παρουσίαση του αλγορίθμου χωρίζεται σε δύο (2) μέρη: ένα για τις "μονές" μονάδες επεξεργασίας (1,3,5,7) και ένα για τις "ζυγές" μονάδες επεξεργασίας( 2,4,6,8). Στο δεύτερο βήμα του αλγορίθμου η πρώτη και η τελευταία μονάδα επεξεργασίας δεν συμμετέχουν, οπότε θα πρέπει να βρίσκονται σε ελεγχόμενη αδράνεια, δηλαδή να περιμένουν μέχρι να ολοκληρωθεί η διαδικασία του δεύτερου βήματος από τις υπόλοιπες μονάδες επεξεργασίας. Συνολικά λοιπόν υπάρχουν τέσσερις (4) παραλλαγές του βασικού κώδικα στις οποίες δίνουμε ονόματα: Odd_Left, Odd_Middle, Even_Middle, Even_Right.
Ο ψευδοκώδικας δίνεται παρακάτω:
W1 <-- read_data for i = 1 to 4 // first phase // if (even) then SEND(left) <-- W1 if (odd) then W2 <-- RECEIVE(right) if (odd) then if W1 < W2 then swap(W1,W2) endif if (odd) then SEND(right) <-- W2 if (even) then W1 <-- RECEIVE(left)
//second phase // if (odd & not leftmost) then SEND(left) <-- W1 if (even & not rightmost) then W2 <-- RECEIVE(right) if (even & not rightmost) then if W1 < W2 then swap(W1,W2) endif if (even & not rightmost) then SEND(right) <-- W2 if (odd & not leftmost) then W1 <-- RECEIVE(left) next i Write_data(W1) |
4) Κώδικας
Ο κώδικας δίνεται στον παρακάτω πίνακα:
;Odd_L ;================= ; read value MOV PORTA,W1 AND W1,W4,W1 ;================= ; Set counter MOV #4,W7 ;================= loop: setup_RxD_RP12 ;================= ; send data NOP ;================= wait ;================= ; receive data MOV U1RXREG,W2 ;================= ; compare-exchange CP W1,W2 BRA LE,labA MOV W1,W3 MOV W2,W1 MOV W3,W2 BRA labB labA: NOP NOP NOP NOP labB : ;================= ; send data MOV W2,U1TXREG ;================= wait ;================= ; receive data NOP ;================= NOP NOP NOP NOP NOP NOP NOP NOP ;================= ; send data NOP ;================= wait ;================= ; receive data NOP ;================= ; compare-exchange NOP NOP NOP NOP NOP NOP NOP ;================= ; send data NOP ;================= wait ;================= ; receive data NOP ;================= DEC W7,W7 BRA NZ,loop ;================= ; Write value AND W1,W4,W1 SL W1,#3,W1 MOV W1,PORTA |
;Even_M ;================= ; read value MOV PORTA,W1 AND W1,W4,W1 ;================= ; Set counter MOV #4,W7 ;================= loop: setup_RxD_RP14 ;================= ; send data MOV W1,U1TXREG ;================= wait ;================= ; receive data NOP ;================= ; compare-exchange NOP NOP NOP NOP NOP NOP NOP ;================= ; send data NOP ;================= wait ;================= ; receive data MOV U1RXREG,W1 ;================= setup_RxD_RP12 ;================= ; send data NOP ;================= wait ;================= ; receive data MOV U1RXREG,W2 ;================= ; compare-exchange CP W1,W2 BRA LE,labA MOV W1,W3 MOV W2,W1 MOV W3,W2 BRA labB labA: NOP NOP NOP NOP labB : ;================= ; send data MOV W2,U1TXREG ;================= wait ;================= ; receive data NOP ;================= DEC W7,W7 BRA NZ,loop ;================= ; Write value AND W1,W4,W1 SL W1,#3,W1 MOV W1,PORTA |
;Odd_M ;================= ; read value MOV PORTA,W1 AND W1,W4,W1 ;================= ; Set counter MOV #4,W7 ;================= loop: setup_RxD_RP12 ;================= ; send data NOP ;================= wait ;================= ; receive data MOV U1RXREG,W2 ;================= ; compare-exchange CP W1,W2 BRA LE,labA MOV W1,W3 MOV W2,W1 MOV W3,W2 BRA labB labA: NOP NOP NOP NOP labB : ;================= ; send data MOV W2,U1TXREG ;================= wait ;================= ; receive data NOP ;================= setup_RxD_RP14 ;================= ; send data MOV W1,U1TXREG ;================= wait ;================= ; receive data NOP ;================= ; compare-exchange NOP NOP NOP NOP NOP NOP NOP ;================= ; send data NOP ;================= wait ;================= ; receive data MOV U1RXREG,W1 ;================= DEC W7,W7 BRA NZ,loop ;================= ; Write value AND W1,W4,W1 SL W1,#3,W1 MOV W1,PORTA |
;Even_R ;================= ; read value MOV PORTA,W1 AND W1,W4,W1 ;================= ; Set counter MOV #4,W7 ;================= loop: setup_RxD_RP14 ;================= ; send data MOV W1,U1TXREG ;================= wait ;================= ; receive data NOP ;================= ; compare-exchange NOP NOP NOP NOP NOP NOP NOP ;================= ; send data NOP ;================= wait ;================= ; receive data MOV U1RXREG,W1 ;================= NOP NOP NOP NOP NOP NOP NOP NOP ;================= ; send data NOP ;================= wait ;================= ; receive data NOP ;================= ; compare-exchange NOP NOP NOP NOP NOP NOP NOP ;================= ; send data NOP ;================= wait ;================= ; receive data NOP ;================= DEC W7,W7 BRA NZ,loop ;================= ; Write value AND W1,W4,W1 SL W1,#3,W1 MOV W1,PORTA |
- Στο τμήμα "read_value" οι μονάδες επεξεργασίας διαβάζουν τα δεδομένα (Το W4 έχει τιμή 0x0003 (mask pattern: επιτρέπει μόνο τα δύο LSBits)
- Στο τμήμα "set_counter" καθορίζεται ο αριθμός των επαναλήψεων του βρόχου (τέσσερις φορές, 4= Ν/2)
- Στο επόμενο τμήμα γίνεται αποστολή δεδομένων από τις "ζυγές" μονάδες στις "μονές".
- Στο τμήμα "compare-exchange" οι μονές Μ.Ε. κάνουν τη σύγκριση και αν χρειάζεται την ανταλλαγή (swap) των δεδομένων.
- Στο επόμενο τμήμα γίνεται αποστολή δεδομένων από τις "μονές" μονάδες στις "ζυγές". Στο σημείο αυτό ολοκληρώνεται το πρώτο βήμα του αλγορίθμου.
- Στα επόμενα τμήματα μεταδίδονται δεδομένα από τις "μονές" Μ.Ε. στις "ζυγές" Μ.Ε., οι "ζυγές" Μ.Ε. κάνουν την σύγκριση και ανταλλαγή (swap) και την αποστολή των τιμών στις "μονές" Μ.Ε.
- Η διαδικασία επαναλαμβάνεται τέσσερις (4) φορές.
- Στο τμήμα "write_value" οι μονάδες επεξεργασίας γράφουν τις (ταξινομημένες πια) τιμές στην PortA.
Οι macros που χρησιμοποιούνται είναι:
.macro wait MOV #100,W8 2: NOP DEC W8,W8 BRA NZ,2b .endm |
.macro setup_RxD_RP14 MOV #0x0008,W6 MOV W6,U1MODE MOV #0x1F0E,W6 MOV W6,RPINR18 MOV #0x8008,W6 MOV W6,U1MODE MOV #0x04C0,W6 MOV W6,U1STA .endm |
.macro setup_RxD_RP12 MOV #0x0008,W6 MOV W6,U1MODE MOV #0x1F0C,W6 MOV W6,RPINR18 MOV #0x8008,W6 MOV W6,U1MODE MOV #0x04C0,W6 MOV W6,U1STA .endm |
Οι εντολές NOP εισάγονται για vα κρατούν τις MCUs σε πλήρη συγχρονισμό.
Τα αρχεία βρίσκονται στο συμπιεσμένο αρχείο Parallel_PIC_Sort_LA_WideIO.zip. Το αρχείο “Sort.s” κρατάει τον πηγαίο κώδικα σε assembly για την αριστερή MCU. Όταν το πρόγραμμα μεταγλωττιστεί, το αρχείο hex που θα παραχθεί θα πρέπει να μετονομαστεί με το χέρι (αυτό έχει ήδη γίνει και το αρχείο έχει ονομαστεί “Sort_Odd_L.hex”). Μετά ο χρήστης θα πρέπει να αλλάξει την directive “.set column, Odd_L” σε “.set column,Odd_M", μετά σε Even_M και Even_R”, και κάθε φορά να ξαναγίνεται μεταγλώττιση και μετονομασία του αρχείου hex. Μετά από τις μεταγλωττίσεις, ο χρήστης μπορεί να χρησιμοποιήσει το λογισμικό για το PC για να μεταφέρει τον κώδικα στους μικροελεγκτές.
Στη σελίδα που περιγράφει τον ParallelPIC παρουσιάζεται και μια εναλλακτική πρόταση που επιταχύνει την εκτέλεση του αλγόριθμου.