Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε

Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε

Υλοποίηση μεταφραστή C με επεκτάσεις OpenMP Λεοντιάδης Ηλίας Τζούμας Γεώργιος Πτυχιακή εργασία Τελική παρουσίαση Υπεύθυνος καθηγητής Β. Β. Δημακόπουλος.

Παρόμοιες παρουσιάσεις


Παρουσίαση με θέμα: "Υλοποίηση μεταφραστή C με επεκτάσεις OpenMP Λεοντιάδης Ηλίας Τζούμας Γεώργιος Πτυχιακή εργασία Τελική παρουσίαση Υπεύθυνος καθηγητής Β. Β. Δημακόπουλος."— Μεταγράφημα παρουσίασης:

1 Υλοποίηση μεταφραστή C με επεκτάσεις OpenMP Λεοντιάδης Ηλίας Τζούμας Γεώργιος Πτυχιακή εργασία Τελική παρουσίαση Υπεύθυνος καθηγητής Β. Β. Δημακόπουλος

2 Παράλληλη επεξεργασία  Λύση σε προβλήματα που είναι πολύ μεγάλα για έναν μόνο επεξεργαστή  Χωρισμός του προβλήματος σε μικρότερα κομμάτια  Ανάθεση του κάθε κομματιού σε έναν επεξεργαστή  Σύνθεση του τελικού αποτελέσματος

3 Μοντέλα παράλληλου προγραμματισμού  Μοντέλο κοινής μνήμης Κοινή μνήμη CPU RAM Message  Μοντέλο μεταβίβασης μηνυμάτων

4 Κλασσικός παράλληλος προγραμματισμός  Ο προγραμματιστής είναι υπεύθυνος για τον διαχωρισμό του προγράμματος σε διεργασίες / threads και την τοποθέτηση τους στους επεξεργαστές.

5 OpenMP C/C++ API  Είναι ένα σύνολο από –εντολές (directives) –ρουτίνες βιβλιοθήκης –μεταβλητές περιβάλλοντος  Προστίθενται στον σειριακό κώδικα και καθοδηγούν τον compiler έτσι ώστε να παραλληλοποιήσει τον κώδικα για εκτέλεση σε περιβάλλον πολυεπεξεργαστών κοινής μνήμης  Αυτή τη στιγμή το πρότυπο αυτό βρίσκεται στην έκδοση 2.0 και μπορείτε να το βρείτε ολόκληρο στο

6 OpenMP directives  Τα directives είναι της μορφής #pragma omp directive-name [clause[clause] …] •parallel Work-sharing •for •section •Single Data environment •threadprivate Synchronization •critical •atomic •barrier •ordered •flush Clauses •shared •private •firstprivate •lastprivate •reduction •copyin •ordered •nowait •schedule

7 Runtime βιβλιοθήκη  Παράλληλο περιβάλλον –omp_set_num_threads() –omp_get_num_threads() –omp_get_thread_num() –omp_get_num_procs() –omp_in_parallel() –omp_set_dynamic() –omp_get_dynamic() –omp_set_nested() –omp_get_nested()  Κλειδαριές –omp_init_lock() –omp_destroy_lock() –omp_set_lock() –omp_unset_lock() –omp_test_lock() −omp_init_nestlock() −omp_destroy_nestlock() −omp_set_nestlock() −omp_unset_nestlock() −omp_test_nestlock()

8 Μεταβλητές περιβάλλοντος  OMP_SCHEDULE  OMP_NUM_THREADS  OMP_DYNAMIC  OMP_NESTED

9 Παράδειγμα κώδικα int main() { int i; int A[10]; /* Serial Code... */ #pragma omp parallel shared(A) { #pragma omp for #pragma omp for for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) { A[i] = 0; A[i] = 0; } } /* Serial Code... */ /* Serial Code... */ return 0; }

10 Πλεονεκτήματα OpenMp  Είναι ένα κοινά αποδεκτό πρότυπο.  Μεταφερσιμότητα  Εύκολη μετάβαση από το σειριακό πρόγραμμα στο παράλληλο  Παραλληλοποίηση καθοδηγούμενη από το χρήστη – απλότητα compiler

11 Άλλες Υλοποιήσεις  OdinMP: A Free, Portable OpenMP Implementation for C  Omni: OpenMP Compiler Project for C and F77

12 Η υλοποίησή μας OpenMP C API  Εξολοκλήρου σε C  GNU Flex / Bison  Παράγει κώδικα C με POSIX Threads  Πληρεί την έκδοση 1.0 του προτύπου  Ήδη υποστηρίζονται κάποιες επεκτάσεις της 2.0

13 POSIX threads  Κάθε νήμα εκτελεί μια συνάρτηση  Μόνο οι global μεταβλητές είναι κοινές  Περιέχουν συναρτήσεις για συγχρονισμό, ατομικότητα, δημιουργία/καταστροφή νημάτων.

14 Παράδειγμα μετασχηματισμού κώδικα parallel void main() { int a; #pragma omp parallel shared(a) { a++; a++; }}

15 Παραγόμενος κώδικας (1/3) Δομή που παράγεται: typedef struct { int (*a); int (*a); } main_parallel_0_vars;

16 Παραγόμενος κώδικας (2/3) void *main_parallel_0 (void *_omp_thread_data) { int _omp_dummy = _omp_assign_key(_omp_thread_data); int _omp_dummy = _omp_assign_key(_omp_thread_data); int (*a) = &_OMP_VARREF (main_parallel_0, a); int (*a) = &_OMP_VARREF (main_parallel_0, a); { (*(a))++; (*(a))++; } return 0; return 0;}

17 Παραγόμενος κώδικας (3/3) void main () { int a; int a; /* #pragma omp parallel shared(a) */ { _OMP_PARALLEL_DECL_VARSTRUCT(main_parallel_0); _OMP_PARALLEL_DECL_VARSTRUCT(main_parallel_0); _OMP_PARALLEL_INIT_VAR (main_parallel_0, a); _OMP_PARALLEL_INIT_VAR (main_parallel_0, a); _omp_create_team (_OMP_THREAD, main_parallel_0, _omp_create_team (_OMP_THREAD, main_parallel_0, (void *)&main_parallel_0_var); (void *)&main_parallel_0_var); _omp_destroy_team (_OMP_THREAD->parent); _omp_destroy_team (_OMP_THREAD->parent); }}

18 Παράδειγμα μετασχηματισμού sections int i; int i; #pragma omp sections lastprivate(i) { #pragma omp section i = 1; i = 1; #pragma omp section i = 2; i = 2; #pragma omp section i = 3; i = 3; }

19 Παραγόμενος κώδικας int i; int i; /* #pragma omp sections lastprivate(i) */ { int (*_omp_firstlastprivate_i) = &i; int (*_omp_firstlastprivate_i) = &i; int i; int i; { int _omp_section_job; int _omp_section_job; _omp_init_sections (1, _omp_num_section[1]); _omp_init_sections (1, _omp_num_section[1]); while (1) { while (1) { _omp_section_job = _omp_get_next_section (1); _omp_section_job = _omp_get_next_section (1); if (_omp_section_job < 0) break; if (_omp_section_job < 0) break; switch (_omp_section_job) { switch (_omp_section_job) { case 0: case 0: i = 1; break; i = 1; break; case 1: /* section */ case 1: /* section */ i = 2; break; i = 2; break; case 2: /* section */ case 2: /* section */ i = 3; break; i = 3; break; } /* switch */ } /* switch */ if (_omp_section_job == 2) { if (_omp_section_job == 2) { *_omp_firstlastprivate_i = i; *_omp_firstlastprivate_i = i; } } /* while */ } /* while */ } _omp_barrier_wait (&_OMP_THREAD->parent->barrier); _omp_barrier_wait (&_OMP_THREAD->parent->barrier); _omp_flush_all (); /* implied flush */ _omp_flush_all (); /* implied flush */ }

20 Παράδειγμα μετασχηματισμού for #pragma omp for for (i = 0; i < 100; i += 3) for (i = 0; i < 100; i += 3) printf("%d\n", i); printf("%d\n", i);

21 Παραγόμενος κώδικας (1/2) int i; int i; /* #pragma omp for */ { int i; int i; int _omp_lb, _omp_ub, _omp_incr; int _omp_lb, _omp_ub, _omp_incr; int _omp_num_job = 0, _omp_last_iter = 0; int _omp_num_job = 0, _omp_last_iter = 0; int _omp_schedule, _omp_chunksize = -1; int _omp_schedule, _omp_chunksize = -1; _omp_schedule = _OMP_DYNAMIC; _omp_schedule = _OMP_DYNAMIC; _omp_chunksize = 1; _omp_chunksize = 1; if (_omp_chunksize < 0) if (_omp_chunksize < 0) _omp_chunksize = _omp_get_default_chunksize (_omp_schedule, 100, 0, 3); _omp_chunksize = _omp_get_default_chunksize (_omp_schedule, 100, 0, 3); _omp_incr = (3); _omp_incr = (3); _omp_init_directive (_OMP_FOR, 0, 0, _omp_incr, 0); _omp_init_directive (_OMP_FOR, 0, 0, _omp_incr, 0); _omp_incr *= _omp_chunksize; _omp_incr *= _omp_chunksize;

22 Παραγόμενος κώδικας (2/2) while (1) { while (1) { /* get next job */ /* get next job */ _omp_lb = _omp_get_next_lb (_omp_schedule, 0, _omp_incr, &_omp_num_job); _omp_lb = _omp_get_next_lb (_omp_schedule, 0, _omp_incr, &_omp_num_job); /* if none left, break */ /* if none left, break */ if (!(_omp_lb - _omp_incr < 100)) break; if (!(_omp_lb - _omp_incr < 100)) break; _omp_ub = _omp_lb + _omp_incr; _omp_ub = _omp_lb + _omp_incr; if (100 <= _omp_ub) { /* check if out of bounds */ if (100 <= _omp_ub) { /* check if out of bounds */ _omp_ub = 100; _omp_ub = 100; _omp_last_iter = 1; _omp_last_iter = 1; } _omp_push_for_data (0, _omp_lb); _omp_push_for_data (0, _omp_lb); for (i = _omp_lb; i < _omp_ub; i += 3) for (i = _omp_lb; i < _omp_ub; i += 3) printf ("%d\n", i); /* original code */ printf ("%d\n", i); /* original code */ _omp_pop_for_data (); _omp_pop_for_data (); } /* while */ } /* while */ _omp_barrier_wait (&_OMP_THREAD->parent->barrier); _omp_barrier_wait (&_OMP_THREAD->parent->barrier); _omp_flush_all (); /* implied flush */ _omp_flush_all (); /* implied flush */ }

23 Παράδειγμα μετασχηματισμού single #pragma omp single printf("I am a single thread!\n"); printf("I am a single thread!\n");

24 Παραγόμενος κώδικας /* #pragma omp single */ { /* the first thread executes the code */ if (_omp_run_single (0)) { if (_omp_run_single (0)) { printf ("I am a single thread!\n"); printf ("I am a single thread!\n"); } _omp_barrier_wait (&_OMP_THREAD->parent->barrier); _omp_barrier_wait (&_OMP_THREAD->parent->barrier); _omp_flush_all (); /* implied flush */ _omp_flush_all (); /* implied flush */ }

25 Παράδειγμα μετασχηματισμού critical int x, y; int x, y; #pragma omp critical (alpha) x++; x++; #pragma omp critical (beta) y++; y++; #pragma omp critical (alpha) x*=2; x*=2;

26 Παραγόμενος κώδικας int x, y; int x, y; /* #pragma omp critical (alpha) */ pthread_mutex_lock (&_omp_critical_lock[0]); pthread_mutex_lock (&_omp_critical_lock[0]); _omp_flush_all (); /* implied flush */ _omp_flush_all (); /* implied flush */ x++; x++; _omp_flush_all (); /* implied flush */ _omp_flush_all (); /* implied flush */ pthread_mutex_unlock (&_omp_critical_lock[0]); pthread_mutex_unlock (&_omp_critical_lock[0]); /* #pragma omp critical (beta) */ pthread_mutex_lock (&_omp_critical_lock[1]); pthread_mutex_lock (&_omp_critical_lock[1]); _omp_flush_all (); /* implied flush */ _omp_flush_all (); /* implied flush */ y++; y++; _omp_flush_all (); /* implied flush */ _omp_flush_all (); /* implied flush */ pthread_mutex_unlock (&_omp_critical_lock[1]); pthread_mutex_unlock (&_omp_critical_lock[1]); /* #pragma omp critical (alpha) */ pthread_mutex_lock (&_omp_critical_lock[0]); pthread_mutex_lock (&_omp_critical_lock[0]); _omp_flush_all (); /* implied flush */ _omp_flush_all (); /* implied flush */ x *= 2; x *= 2; _omp_flush_all (); /* implied flush */ _omp_flush_all (); /* implied flush */ pthread_mutex_unlock (&_omp_critical_lock[0]); pthread_mutex_unlock (&_omp_critical_lock[0]);

27 Επιδόσεις (compilation)

28 Επιδόσεις (runtime)

29 Επιδόσεις (speedup)

30 Επιδόσεις (overhead)

31 Αναφορές  OpenMp official web site  OdinMP  Omni


Κατέβασμα ppt "Υλοποίηση μεταφραστή C με επεκτάσεις OpenMP Λεοντιάδης Ηλίας Τζούμας Γεώργιος Πτυχιακή εργασία Τελική παρουσίαση Υπεύθυνος καθηγητής Β. Β. Δημακόπουλος."

Παρόμοιες παρουσιάσεις


Διαφημίσεις Google