Threading Building Blocks. Σύνοψη  Γενικά για TBBs  Tasks  Parallel for  Εσωτερική λειτουργία βιβλιοθήκης  Task graphs.

Slides:



Advertisements
Παρόμοιες παρουσιάσεις
ΓΙΩΡΓΟΣ ΣΕΦΕΡΗΣ
Advertisements

Comparative vs. Superlative
Σεφέρης Ομιλία Στοκχόλμης, απονομή Νόμπελ 1963
ΠΟΛΙΤΙΚΕΣ ΝΑΥΛΩΣΕΩΝ ΚΑΙ ΣΤΡΑΤΗΓΙΚΕΣ ΜΑΡΚΕΤΙΝΓΚ ΤΩΝ ΕΛΛΗΝΙΚΩΝ ΝΑΥΤΙΛΙΑΚΩΝ ΕΠΙΧΕΙΡΗΣΕΩΝ Δρ. ΕΥΗ ΠΛΩΜΑΡΙΤΟΥ.
1 NAVIGON 40 Easy Comfort Edition NAVIGON 40 Easy Comfort Edition.
NOT TOO YUPPIE Καβρουδάκης Φραγκίσκος ( Μαραγκός Άγγελος ( B λαβιανός Ηλίας.
Δίκτυα Η/Υ ΙΙ Έλεγχος Συμφόρησης Congestion Control.
ΑΛΓΟΡΙΘΜΙΚΗ ΠΡΟΣΕΓΓΙΣΗ ΣΤΙΣ ΓΕΩΓΡΑΦΙΚΕΣ ΜΕΘΟΔΟΥΣ ΔΡΟΜΟΛΟΓΗΣΗΣ ΣΕ AD HOC ΔΙΚΤΥΑ & ΛΟΓΙΚΑ ΚΥΚΛΩΜΑΤΑ Ελένη Παπαντωνίου.
Εισαγωγή στη Βιοπληροφορική
DATA MINING LECTURE 6 Mixture of Gaussians and the EM algorithm
1 Basic network tools Layers recap Basic Addressing ping traceroute ipconfig.
Αντώνης Σιδηρόπουλος Τμήμα Πληροφορικής ΤΕΙ Θεσσαλονίκης MPI Jacobi iterations.
IT2000 vs IT2012 By Fotis Lavdas & Menelaos Makrigiannis.
PRESENT CONTINUOUS MARY P. 4TH GRADE.
ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΤΜΗΜΑ ΜΗΧΑΝΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΒΙΟΜΗΧΑΝΙΑΣ Διάλεξη 11: Χρήση δομών, εξωτερικών αρχείων και γραφικών στο Matlab Εαρινό εξάμηνο 2008.
ΣYMBOΛIKOΣ ΥΠΟΛΟΓΙΣΜΟΣ. ΣYMBOΛIKOΣ ΥΠΟΛΟΓΙΣΜΟΣ - Παράδειγμα %polynomial (Expression, Variable) polynomial (X, X). polynomial (Term, X) :- number (Term).
Natural Language Toolkit
Πανεπιστήμιο Πατρών, Τμήμα Ηλεκτρολόγων Μηχανικών & Τεχνολογίας Υπολογιστών Αρχιτεκτονικές VLIW Στέφανος Καξίρας {
Προβλήματα Προσχεδιασμού. Ο κόσμος των κύβων Πρόβλημα προσχεδιασμού κατάλληλων πύργων Η Κατάσταση του κόσμου μπορεί να αναπαρασταθεί με μια λίστα από:
MOBILITY (MOBILE IP).
TEMPLATES, STL ΠΡΟΓΡΑΜΜΑΤΑ ΜΕ ΠΟΛΛΑ ΑΡΧΕΙΑ. ΑΝΑΚΕΦΑΛΑΙΩΣΗ.
Examples in XSB Prolog Επεξεργασία και Αναπαράσταση Γνώσης Άνοιξη 2010 Τμήμα Επιστήμης Υπολογιστών Πανεπιστημίου Κρήτης.
Ρυθμίσεις Android phones για MMS και Internet. 20/6/2013 Although every effort has been taken, this DRAFT technical paper has been prepared in good faith.
Transactional Memory. Τα προβλήματα του παράλληλου προγραμματισμού  Εντοπισμός παραλληλισμού – χειροκίνητα (επισκόπηση) – αυτόματα (compiler)  Έκφραση.
Ασκηση NextGen POS. Ι. Δεληγιάννης, Τμ. Πληροφορικής ΤΕΙ-Θ UNIFIED PROCESS - ΑΝΑΛΥΣΗ2.
Αντικειμενοστρεφής Προγραμματισμός Κλάσεις και άλλα θέματα Απόστολος Ζάρρας * βασισμένα και σε δουλειά του.
Η Σημερινή Εικόνα του Οδηγού Σπουδών Κ. Λαμπρινουδάκης Τμήμα Μηχανικών Πληροφοριακών και Επικοινωνιακών Συστημάτων.
Distance Functions on Hierarchies
Τι θα φέρει το Σύννεφο στη Διαχείριση Δεδομένων: Προκλήσεις και Ευκαιρίες Ελληνικό Συμπόσιο Διαχείρισης Δεδομένων 2010 Ευαγγελία Πιτουρά Τμήμα Πληροφορικής,
Assembler source. Editor and message windows 1)ASSEMBLER DIRECTIVES Change or adjust the way the assembler works with the code.
Διαχείριση Δικτύων Ευφυή Δίκτυα Άσκηση 3 DOMAIN NAME SYSTEM (DNS) Εργαστήριο Διαχείρισης και Βέλτιστου Σχεδιασμού Δικτύων (NETMODE)
Πανεπιστήμιο Πατρών ΟΝΤΟΚΕΝΤΡΙΚΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΙΙ (C++)
Μεθοδολογίες Προγραμματισμού ΙΙ ΣΧΕΔΙΑΣΤΙΚΑ ΠΡΟΤΥΠΑ (2)
Πληροφοριακά Συστήματα και Βάσεις Δεδομένων
Εισαγωγικό Φροντηστήριο Διαχείριση Περιεχομένου Παγκόσμιου Ιστού και Γλωσσικά Eργαλεία.
A model for Context-aware Databases. 19/04/20052 What is Context? Ο καθένας ορίζει το context διαφορετικά... “location, identities of nearby people and.
Εισαγωγή στην Compute Unified Device Architecture (CUDA)
Lesson 14: Around the city JSIS E 111: Elementary Modern Greek Sample of modern Greek alphabet, M. Adiputra,
Lesson 28a: Shopping at Costco JSIS E 111: Elementary Modern Greek Sample of modern Greek alphabet, M. Adiputra,
ΠΟΛΥΜΟΡΦΙΣΜΟΣ, ΠΡΟΤΥΠΑ, ΚΑΘΙΕΡΩΜΕΝΗ ΒΙΒΛΙΟΘΗΚΗ ΠΡΟΤΥΠΩΝ Polymorphism, Templates, Standard Template Library (STL)
Γειά σας. Say: Nick is going to the supermarket.
Lesson 18b: At the University JSIS E 111: Elementary Modern Greek Sample of modern Greek alphabet, M. Adiputra,
Comenius E.R.G.O Equal Rights Great Opportunities Presentation by the Greek Delegation to Hungary.
Lesson 20a: Nature I JSIS E 111: Elementary Modern Greek Sample of modern Greek alphabet, M. Adiputra,
Visual Studio 2010 Load Testing Γιώργος Καρκαλής Testing Specialist 12/5/2011.
Lesson 18c: At the University JSIS E 111: Elementary Modern Greek Sample of modern Greek alphabet, M. Adiputra,
Lesson 32a: Trasportation JSIS E 111: Elementary Modern Greek Sample of modern Greek alphabet, M. Adiputra,
Lesson 41c: Cooking I JSIS E 111: Elementary Modern Greek Sample of modern Greek alphabet, M. Adiputra,
Lesson 52a: Nick’s mom JSIS E 111: Elementary Modern Greek Sample of modern Greek alphabet, M. Adiputra,
Πολυδιάστατοι Πίνακες – Multidimensional arrays πίνακας με δύο ή περισσότερες διαστάσεις float student_grades[NUM_STUDENTS][NUM_COURSES];
Παρουσίαση του εργαλείου Rundeck και use cases Αθήνα 16/01/2014 Κωνσταντίνος Χρηστίδης ~ Εθνικό Κέντρο Τεκμηρίωσης Τμήμα Ηλεκτρονικών Υποδομών.
Γλώσσα περιγραφής υλικού VHDL. Βασική δομή VHDL κώδικα Entity Entity (Δήλωση εισόδων – εξόδων του συστήματος) Architecture Architecture structural (περιγραφή.
 You need textbooks today. If they are in your locker – get them NOW!  Don’t ask once class has started…
1 Τμήμα Μηχανικών Ηλεκτρονικών Υπολογιστών και Πληροφορικής Πανεπιστήμιο Πατρών ΟΝΤΟΚΕΝΤΡΙΚΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΙΙ (C++) Δείκτες και Συμβολοσειρές (Pointers.
ΕΝΟΤΗΤΑ 9Η Η ΓΛΩΣΣΑ VHDL: ΣΥΝΔΥΑΣΤΙΚΑ ΚΥΚΛΩΜΑΤΑ
«Εἰς ἀπολογίαν τοῦ Εὐαγγελίου» (Φιλιππησίους 1, 17). Ἀπαντήσεις σὲ σύγχρονες προκλήσεις.
Ἡ μερίδα Συνοδικ ῆ ς Ἐ πιτροπ ῆ ς Θείας Λατρείας καί Ποιμαντικο ῦ Ἔ ργου «Τό πνε ῦ μα ὅ που θέλει πνε ῖ » ( Ἰ ωάννου 3,8) Ὀ ρθόδοξη πνευματική ζωή - Σύγχρονοι.
11. Ιγνάτιος ο Θεοφόρος Αποστολικός πατέρας Αποστολική παράδοση Φρόνημα, διδασκαλία, τρόπος ζωής των αποστόλων Αποστολικοί Πατέρες Εκκλησιαστικές προσωπικότητες.
Λίγα λόγια για τον Κωσταντίνο Καβάφη
Ἱερὰ Μονὴ Σταυρονικήτα Βρίσκεται στὴν ἀνατολικὴ ἀκτὴ τοῦ Ἁγίου Ὅρους σὲ ὑψόμετρο 50μ. ἀπὸ τὴν ἐπιφάνεια τῆς θάλασσας. Εἶναι ἡ τελευταία ἀπὸ τὶς μονὲς.
Ἱστορία ἀρχαία καὶ μεσαιωνικὴ
Γενικὴ Ἐκκλησιαστικὴ Ἱστορία Α´
JULIUS CAESAR Ἰούλιος Καῖσαρ.
Ἱστορία ἀρχαία καὶ μεσαιωνικὴ
Αναστάσιμη Προσευχή ΧΡΙΣΤΟΣ ΑΝΕΣΤΗ!.
Ἱστορία ἀρχαία καὶ μεσαιωνικὴ
Ἱστορία τοῦ Νεότερου καὶ Σύγχρονου Κόσμου ἀπὸ τὸ 1453 ἕως σήμερα
Ἱστορία τοῦ νεώτερου καὶ τοῦ σύγχρονου κόσμου (ἀπὸ τὸ 1815 ἕως σήμερα)
Croy 7 - Exercises 1. λέγετε λόγον κατὰ τοῦ κυρίου τοῦ οὐρανοῦ;
Baggy Bounds checking by Akritidis, Costa, Castro, and Hand
Μεταγράφημα παρουσίασης:

Threading Building Blocks

Σύνοψη  Γενικά για TBBs  Tasks  Parallel for  Εσωτερική λειτουργία βιβλιοθήκης  Task graphs

Σύνοψη  Γενικά για TBBs  Tasks  Parallel for  Εσωτερική λειτουργία βιβλιοθήκης  Task graphs

Τι είναι τα TBBs;  C++ template library για αποδοτικό και εύκολο παράλληλο προγραμματισμό σε πλατφόρμες μοιραζόμενης μνήμης  Αναπτύσσεται από την Intel από το 2004 (open-source από το 2007)  Δεν είναι καινούρια γλώσσα ή επέκταση  Μεταφέρσιμη στους περισσότερους C++ compilers, λειτουργικά συστήματα και αρχιτεκτονικές

Βασικά χαρακτηριστικά 1. Ο προγραμματιστής ορίζει tasks αντί για threads – επικεντρώνεται στην έκφραση του παραλληλισμού στην εφαρμογή (σε υψηλότερο ή χαμηλότερο επίπεδο) – η βιβλιοθήκη είναι υπεύθυνη για την υλοποίησή του •διάσπαση συνολικής δουλειάς σε επιμέρους εργασίες •δρομολόγηση εργασιών στους επεξεργαστές •συγχρονισμός •ισοκατανομή φορτίου •διαχείριση πόρων συστήματος και εσωτερικών μηχανισμών

Βασικά χαρακτηριστικά 2. Σχεδιασμένη για κλιμακωσιμότητα – η συνολική δουλειά σπάει σε πολλά μικρά κομμάτια (tasks), συνήθως πολύ περισσότερα από τον αριθμό των επεξεργαστών («parallel slack») – εξασφαλίζεται ότι θα υπάρχει πάντα διαθέσιμη δουλειά για κάθε επιπλέον επεξεργαστή που προστίθεται – ο μηχανισμός για load balancing εξασφαλίζει την κλιμακώσιμη απόδοση

Βασικά χαρακτηριστικά 3. Εκμεταλλεύεται τη δύναμη και την ευελιξία του γενικευμένου προγραμματισμού (generic programming) – παρέχει ένα πλούσιο σύνολο από παραμετροποιήσιμα (templated), «ready to use» παράλληλα αλγοριθμικά μοτίβα και δομές •αντίστοιχα με την C++ STL για τα σειριακά προγράμματα – δεν απαιτεί ειδική υποστήριξη από μεταγλωττιστή

8 TBB 4.0 Components Synchronization primitives atomic mutex recursive_mutex spin_mutex, spin_rw_mutex queuing_mutex, queuing_rw_mutex Synchronization primitives atomic mutex recursive_mutex spin_mutex, spin_rw_mutex queuing_mutex, queuing_rw_mutex Generic Parallel Algorithms parallel_for parallel_reduce parallel_scan parallel_do pipeline, parallel_pipeline, parallel_sort parallel_invoke Generic Parallel Algorithms parallel_for parallel_reduce parallel_scan parallel_do pipeline, parallel_pipeline, parallel_sort parallel_invoke Concurrent containers concurrent_unordered_map, concurrent_unordered_set, concurrent_hash_map, concurrent_queue, concurrent_bounded_queue, concurrent_priority_queue concurrent_vector Concurrent containers concurrent_unordered_map, concurrent_unordered_set, concurrent_hash_map, concurrent_queue, concurrent_bounded_queue, concurrent_priority_queue concurrent_vector Raw tasking task task_group task_list task_scheduler_observer Raw tasking task task_group task_list task_scheduler_observer Memory allocation tbb_allocator cache_aligned_allocator scalable_allocator Memory allocation tbb_allocator cache_aligned_allocator scalable_allocator Flow Graph graph function_node broadcast_node … Flow Graph graph function_node broadcast_node …

9 TBB 4.0 Components Synchronization primitives atomic mutex recursive_mutex spin_mutex, spin_rw_mutex queuing_mutex, queuing_rw_mutex Synchronization primitives atomic mutex recursive_mutex spin_mutex, spin_rw_mutex queuing_mutex, queuing_rw_mutex Generic Parallel Algorithms parallel_for parallel_reduce parallel_scan parallel_do pipeline, parallel_pipeline, parallel_sort parallel_invoke Generic Parallel Algorithms parallel_for parallel_reduce parallel_scan parallel_do pipeline, parallel_pipeline, parallel_sort parallel_invoke Concurrent containers concurrent_unordered_map, concurrent_unordered_set, concurrent_hash_map, concurrent_queue, concurrent_bounded_queue, concurrent_priority_queue concurrent_vector Concurrent containers concurrent_unordered_map, concurrent_unordered_set, concurrent_hash_map, concurrent_queue, concurrent_bounded_queue, concurrent_priority_queue concurrent_vector Raw tasking task task_group task_list task_scheduler_observer Raw tasking task task_group task_list task_scheduler_observer Memory allocation tbb_allocator cache_aligned_allocator scalable_allocator Memory allocation tbb_allocator cache_aligned_allocator scalable_allocator Flow Graph graph function_node broadcast_node … Flow Graph graph function_node broadcast_node …

Σύνοψη  Γενικά για TBBs  Tasks  Parallel for  Εσωτερική λειτουργία βιβλιοθήκης  Task graphs

Tasks  Εκφράζουν μια στοιχειώδη ανεξάρτητη εργασία στο πρόγραμμα του χρήστη – πολύ πιο lightweight από τα native threads του λειτουργικού  Δυνατότητα άμεσης χρήσης των tasks από τον προγραμματιστή – δημιουργία αυθαίρετα πολύπλοκων γράφων εργασιών scheduler tasks parallel algorithms

Προγραμματιστικό μοντέλο  Όπως και στη Cilk, δύο βασικές λειτουργίες για την περιγραφή ενός task graph – spawn: δημιουργία εργασίας – wait: συγχρονισμός εργασιών

Μέθοδος 1 task groups + Lambdas long ParallelFib(long n) { if ( n < 16 ) return SerialFib(n); else { int x, y; tbb::task_group g; g.run( [&]{ x = ParallelFib(n-1); } ); g.run( [&]{ y = ParallelFib(n-2); } ); g.wait(); return x+y; }

Μέθοδος 2 task objects long SerialFib(long n) { if (n < 2) return n; else return SerialFib(n-1) + SerialFib(n-2); } long SerialFib(long n) { if (n < 2) return n; else return SerialFib(n-1) + SerialFib(n-2); } long n, sum; FibTask& r = *new ( allocate_root())FibTask(n,&sum); spawn_root_and_wait(r); cout << sum; long n, sum; FibTask& r = *new ( allocate_root())FibTask(n,&sum); spawn_root_and_wait(r); cout << sum; class FibTask: public task { const long n; long *const sum; FibTask(long n_,long* sum_) { n=n_; sum=sum_; } task* execute() { if (n < cutOff) *sum = SerialFib(n); else { long x,y; FibTask& a = *new ( allocate_child())FibTask(n-1,&x); FibTask& b = *new ( allocate_child())FibTask(n-2,&y); set_ref_count(3); spawn(b); spawn(a); wait_for_all(); *sum = x+y; } return NULL; } }; class FibTask: public task { const long n; long *const sum; FibTask(long n_,long* sum_) { n=n_; sum=sum_; } task* execute() { if (n < cutOff) *sum = SerialFib(n); else { long x,y; FibTask& a = *new ( allocate_child())FibTask(n-1,&x); FibTask& b = *new ( allocate_child())FibTask(n-2,&y); set_ref_count(3); spawn(b); spawn(a); wait_for_all(); *sum = x+y; } return NULL; } };

Μέθοδος 2 task objects long SerialFib(long n) { if (n < 2) return n; else return SerialFib(n-1) + SerialFib(n-2); } long SerialFib(long n) { if (n < 2) return n; else return SerialFib(n-1) + SerialFib(n-2); } class FibTask: public task { const long n; long *const sum; FibTask(long n_,long* sum_) { n=n_; sum=sum_; } task* execute() { if (n < cutOff) *sum = SerialFib(n); else { long x,y; FibTask& a = *new ( allocate_child())FibTask(n-1,&x); FibTask& b = *new ( allocate_child())FibTask(n-2,&y); set_ref_count(3); spawn(b); spawn(a); wait_for_all(); *sum = x+y; } return NULL; } }; class FibTask: public task { const long n; long *const sum; FibTask(long n_,long* sum_) { n=n_; sum=sum_; } task* execute() { if (n < cutOff) *sum = SerialFib(n); else { long x,y; FibTask& a = *new ( allocate_child())FibTask(n-1,&x); FibTask& b = *new ( allocate_child())FibTask(n-2,&y); set_ref_count(3); spawn(b); spawn(a); wait_for_all(); *sum = x+y; } return NULL; } }; each user-defined task must extend tbb::task and implement execute() long n, sum; FibTask& r = *new ( allocate_root())FibTask(n,&sum); spawn_root_and_wait(r); cout << sum; long n, sum; FibTask& r = *new ( allocate_root())FibTask(n,&sum); spawn_root_and_wait(r); cout << sum;

long n, sum; FibTask& r = *new ( allocate_root())FibTask(n,&sum); spawn_root_and_wait(r); cout << sum; long n, sum; FibTask& r = *new ( allocate_root())FibTask(n,&sum); spawn_root_and_wait(r); cout << sum; Μέθοδος 2 task objects long SerialFib(long n) { if (n < 2) return n; else return SerialFib(n-1) + SerialFib(n-2); } long SerialFib(long n) { if (n < 2) return n; else return SerialFib(n-1) + SerialFib(n-2); } class FibTask: public task { const long n; long *const sum; FibTask(long n_,long* sum_) { n=n_; sum=sum_; } task* execute() { if (n < cutOff) *sum = SerialFib(n); else { long x,y; FibTask& a = *new ( allocate_child())FibTask(n-1,&x); FibTask& b = *new ( allocate_child())FibTask(n-2,&y); set_ref_count(3); spawn(b); spawn(a); wait_for_all(); *sum = x+y; } return NULL; } }; class FibTask: public task { const long n; long *const sum; FibTask(long n_,long* sum_) { n=n_; sum=sum_; } task* execute() { if (n < cutOff) *sum = SerialFib(n); else { long x,y; FibTask& a = *new ( allocate_child())FibTask(n-1,&x); FibTask& b = *new ( allocate_child())FibTask(n-2,&y); set_ref_count(3); spawn(b); spawn(a); wait_for_all(); *sum = x+y; } return NULL; } }; allocate root task (has no parent) spawn it, and wait here

long n, sum; FibTask& r = *new ( allocate_root())FibTask(n,&sum); spawn_root_and_wait(r); cout << sum; long n, sum; FibTask& r = *new ( allocate_root())FibTask(n,&sum); spawn_root_and_wait(r); cout << sum; Μέθοδος 2 task objects long SerialFib(long n) { if (n < 2) return n; else return SerialFib(n-1) + SerialFib(n-2); } long SerialFib(long n) { if (n < 2) return n; else return SerialFib(n-1) + SerialFib(n-2); } class FibTask: public task { const long n; long *const sum; FibTask(long n_,long* sum_) { n=n_; sum=sum_; } task* execute() { if (n < cutOff) *sum = SerialFib(n); else { long x,y; FibTask& a = *new ( allocate_child())FibTask(n-1,&x); FibTask& b = *new ( allocate_child())FibTask(n-2,&y); set_ref_count(3); spawn(b); spawn(a); wait_for_all(); *sum = x+y; } return NULL; } }; class FibTask: public task { const long n; long *const sum; FibTask(long n_,long* sum_) { n=n_; sum=sum_; } task* execute() { if (n < cutOff) *sum = SerialFib(n); else { long x,y; FibTask& a = *new ( allocate_child())FibTask(n-1,&x); FibTask& b = *new ( allocate_child())FibTask(n-2,&y); set_ref_count(3); spawn(b); spawn(a); wait_for_all(); *sum = x+y; } return NULL; } }; if n small enough, execute task serially otherwise create and run two tasks

long n, sum; FibTask& r = *new ( allocate_root())FibTask(n,&sum); spawn_root_and_wait(r); cout << sum; long n, sum; FibTask& r = *new ( allocate_root())FibTask(n,&sum); spawn_root_and_wait(r); cout << sum; Μέθοδος 2 task objects long SerialFib(long n) { if (n < 2) return n; else return SerialFib(n-1) + SerialFib(n-2); } long SerialFib(long n) { if (n < 2) return n; else return SerialFib(n-1) + SerialFib(n-2); } class FibTask: public task { const long n; long *const sum; FibTask(long n_,long* sum_) { n=n_; sum=sum_; } task* execute() { if (n < cutOff) *sum = SerialFib(n); else { long x,y; FibTask& a = *new ( allocate_child())FibTask(n-1,&x); FibTask& b = *new ( allocate_child())FibTask(n-2,&y); set_ref_count(3); spawn(b); spawn(a); wait_for_all(); *sum = x+y; } return NULL; } }; class FibTask: public task { const long n; long *const sum; FibTask(long n_,long* sum_) { n=n_; sum=sum_; } task* execute() { if (n < cutOff) *sum = SerialFib(n); else { long x,y; FibTask& a = *new ( allocate_child())FibTask(n-1,&x); FibTask& b = *new ( allocate_child())FibTask(n-2,&y); set_ref_count(3); spawn(b); spawn(a); wait_for_all(); *sum = x+y; } return NULL; } }; allocate child tasks how many children should I wait for? 2 (+1 implicit...) spawn tasks (indicate them as “ready to execute”) ok, now really wait for children to complete merge their results and store into *sum

Σύνοψη  Γενικά για TBBs  Tasks  Parallel for  Εσωτερική λειτουργία βιβλιοθήκης  Task graphs

TBB: Αρχικοποίηση  Για την χρήση οποιουδήποτε παράλληλου αλγόριθμου της βιβλιοθήκης, απαιτείται η δημιουργία ενός αντικειμένου task_scheduler_init #include #define NPROCS 4 int main() { tbb::task_scheduler_init init(NPROCS); … }

Παραλληλοποίηση for-loop  Υπόθεση: εφαρμογή συνάρτησης Foo() σε κάθε στοιχείο ενός πίνακα  Σειριακός κώδικας  Παράλληλος κώδικας float a[100]; for ( int i=0; i!=100; ++i ) Foo(a[i]); tbb::parallel_for( tbb::blocked_range (0,100), [=](const tbb::blocked_range & r) { for ( size_t i = r.begin(); i != r.end(); ++i ) Foo(a[i]); } ); δημιουργία (ανώνυμου) αντικειμένου για την περιγραφή του αρχικού χώρου επαναλήψεων ανώνυμη συνάρτηση (Lambda expression) που περιγράφει τι δουλειά θα γίνεται σε έναν οποιονδήποτε υποχώρο επαναλήψεων του loop

Παραλληλοποίηση for-loop  δήλωση:  η parallel_for αναλαμβάνει: – να διασπάσει το αρχικό range σε πολλά μικρότερα – να εφαρμόσει παράλληλα την ανώνυμη συνάρτηση σε καθένα από αυτά template void parallel_for(const Range& R, const Body& B ); η βιβλιοθήκη παρέχει τις κλάσεις blocked_range, blocked_range2d, blocked_range3d

Chunking και loop partitioners parallel_for( blocked_range (0,n,G), [](){…},,some_partitioner())  Chunking: το μέγεθος των ranges στο οποίο σταματά η αναδρομική διάσπαση – optional argument στον constructor του blocked_range  Partitioners – optional argument στην parallel_for 1. simple_partitioner •recursive binary splitting, εγγυάται ότι G/2 ≤ chunksize ≤ G 2. affinity_partitioner •αναθέτει τα ranges με τρόπο ώστε να μεγιστοποιείται το cache locality 3. auto_partitioner (default) •επιλέγει αυτόματα το grainsize με βάση ευριστική μέθοδο •προσπαθεί να ελαχιστοποιήσει το range splitting σε σημείο που να εξασφαλίζεται καλό load balancing

Σύνοψη  Γενικά για TBBs  Tasks  Parallel for  Εσωτερική λειτουργία βιβλιοθήκης  Task graphs

Λειτουργία parallel_for 0 N P0 P1 P2 P3 A A A αναδρομική διάσπαση του range, μέχρι να γίνει ≤ GrainSize worker threads με double-ended queues bottom (youngest task) top (oldest task)  σε κάθε εκτέλεση της αναδρομής ένα range διασπάται σε 2 subranges  δημιουργούνται 2 νέα tasks που τοποθετούνται στη βάση της ουράς  κάθε worker παίρνει το task από τη βάση της τοπικής του ουράς και το εκτελεί  αν δεν βρει, τότε κλέβει κάποιο από την κορυφή της ουράς ενός τυχαίου worker

Λειτουργία parallel_for 0 N P0 P1 P2 P3 A A A

Λειτουργία parallel_for 0 N P0 P1 P2 P3 A A

Λειτουργία parallel_for 0 N P0 P1 P2 P3 B B N/2 N A B A

Λειτουργία parallel_for 0 N P0 P1 P2 P3 C C 0 N/2N/2 N B B A CB A

Λειτουργία parallel_for 0 N P0 P1 P2 P3 B B 0 N/2N/2 N A CB C

Λειτουργία parallel_for 0 N P0 P1 P2 P3 D D 0 N/2 B B A CB D C

Λειτουργία parallel_for 0 N P0 P1 P2 P3 E E 0 N/2 D D A CB 0 N/4 ED B B C

Λειτουργία parallel_for 0 N P0 P1 P2 P3 E E 0 N/2 D D A CB 0 N/4 ED B B C

Λειτουργία parallel_for 0 N P0 P1 P2 P3 E E B B 0 N/2 D D A CB 0 N/4 ED C

Λειτουργία parallel_for 0 N P0 P1 P2 P3 D D B B 0 N/2 A CB 0 N/4 ED E

Λειτουργία parallel_for 0 - N P0 P1 P2 P3 F F B B 0 - N/2 D D A CB 0 - N/4 ED F E

Λειτουργία parallel_for 0 - N P0 P1 P2 P3 G G B B 0 - N/2 F F A CB 0 - N/4 ED 0 - N/8 GF D D E

Λειτουργία parallel_for 0 - N P0 P1 P2 P3 G G B B 0 - N/2 F F A CB 0 - N/4 ED 0 - N/8 GF D D E

Λειτουργία parallel_for 0 - N P0 P1 P2 P3 G G B B 0 - N/2 F F A CB 0 - N/4 ED 0 - N/8 GF E D D

Βασικοί μηχανισμοί  Work stealing – εξασφαλίζει ισοκατανομή φορτίου  Recursive splitting – επιτρέπει την επεξεργασία πάνω σε αυθαίρετα μικρά κομμάτια και τη βέλτιστη εκμετάλλευση της cache

Σύνοψη  Γενικά για TBBs  Tasks  Parallel for  Εσωτερική λειτουργία βιβλιοθήκης  Task graphs

Generic task graph task groups S(); task_group g; g.run( [&]{ C(); E(); } ); g.run( [&]{ task_group g1; g1.run( [&]{A();} ); g1.run( [&]{B();} ); g1.wait(); D(); }); g.wait(); F();

Generic task graph flow graph graph g; broadcast_node s; continue_node a(g,A()); continue_node b(g,B()); continue_node c(g,C()); continue_node d(g,D()); continue_node e(g,E()); continue_node f(g,F()); make_edge(s,a); make_edge(s,b); make_edge(s,c); make_edge(a,d); make_edge(b,d); make_edge(c,e); make_edge(d,f); make_edge(e,f); S(); s.try_put(continue_msg()); //fire! g.wait_for_all();

Generic task graph task objects + reference counts class MeshTask: public task { public: const int i,j; //coordinates MeshTask *south,*east; task* execute() { double north = (i==0) ? 0 : A[i-1][j]; double west = (j==0) ? 0 : A[i][j-1]; A[i][j] = do_work(north, west); //if there is south neighbor if(south!=NULL) if (!south->decrement_ref_count()) spawn(*south); //if there is east neighbor if(east!=NULL) if (!east->decrement_ref_count()) spawn(*south); return NULL; } class MeshTask: public task { public: const int i,j; //coordinates MeshTask *south,*east; task* execute() { double north = (i==0) ? 0 : A[i-1][j]; double west = (j==0) ? 0 : A[i][j-1]; A[i][j] = do_work(north, west); //if there is south neighbor if(south!=NULL) if (!south->decrement_ref_count()) spawn(*south); //if there is east neighbor if(east!=NULL) if (!east->decrement_ref_count()) spawn(*south); return NULL; } MeshTask* Mesh[4][5]; //for all tasks in Mesh: // allocate // initialize south,east pointers // set reference counters //wait for all but last task to complete Mesh[3][4]->spawn_and_wait_for_all(*Mesh[0][0]); //execute last task Mesh[3][4]->execute(); MeshTask* Mesh[4][5]; //for all tasks in Mesh: // allocate // initialize south,east pointers // set reference counters //wait for all but last task to complete Mesh[3][4]->spawn_and_wait_for_all(*Mesh[0][0]); //execute last task Mesh[3][4]->execute();

Resources  Home –  Latest stable release (4.0): – – use sources  Documentation: – – Getting Started – Tutorial – Reference  Intel Software Network blogs: –  Forum: – blocks/ blocks/

ΤΕΛΟΣ

Extra slides

Lambda Expressions  “C++11 feels like a new language” [B. Stroustrup]  Δυνατότητα “in-place” ορισμού συναρτήσεων στο σημείο που χρησιμοποιούνται – αντί των function objects – o compiler δημιουργεί μοναδικό, ανώνυμο function object για κάθε lambda expression  gcc 4.5 or newer char s[]="Hello World!"; int nup = 0; //modified by the lambda for_each( s, s+sizeof(s), [&nup] (char c) { if (isupper(c)) nup++; } ); cout << nup << " uppercase letters in: "<< s << endl; char s[]="Hello World!"; int nup = 0; //modified by the lambda for_each( s, s+sizeof(s), [&nup] (char c) { if (isupper(c)) nup++; } ); cout << nup << " uppercase letters in: "<< s << endl;

Lambda Syntax 49  [capture_mode] (formal_parameters) -> return_type {body} Can omit if there are no parameters and return type is implicit. Can omit if return type is void or code is “return expr;” [&]  by-reference [=]  by-value []  no capture [&](float x) {sum+=x;} [&]{return *p++;} [=](float x) {return a*x+b;} []{return rand();} [](float x, float y)->float { if(x<y) return x; else return y; } Examples

Γενικευμένος Προγραμματισμός  «... deals with finding abstract representations of efficient algorithms, data structures, and other software concepts, and with their systematic organization» [Czarnecki, Eisenecker – Generative Programming]  «... a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters» [wikipedia]  Σκοπός η ανάπυξη λογισμικού ώστε να είναι επαναχρησιμοποιήσιμο με απλό και αποδοτικό τρόπο

Templates  Επιτρέπουν την παραμετροποίηση τύπων σε συναρτήσεις και κλάσεις  Παράδειγμα templated συνάρτησης template void swap(T & x, T & y) { T tmp = x; x = y; y = tmp; } … float f1,f2; String s1,s2; swap(f1,f2); //template instantiation: swap floats swap(s1,s2); //template instantiation: swap strings Ελάχιστες απαιτήσεις για τον Τ 1. copy constructor T(const T&) 2. assignment operator void T::operator=(const T&); 3. destructor ~T() Ελάχιστες απαιτήσεις για τον Τ 1. copy constructor T(const T&) 2. assignment operator void T::operator=(const T&); 3. destructor ~T()

Templates  Παράδειγμα templated κλάσης template class pair { public: T first; U second; pair( const T & x, const U & y ) : first(x), second(y) {} }; … //compiler instantiates pair with T=string and U=int pair x; x.first = “abc”; x.second = 42;

C++ Standard Template Library (STL)  Ένα από τα πλέον επιτυχημένα παραδείγματα γενικευμένου προγραμματισμού  Παρέχει ένα σύνολο από:  οι καλύτεροι δυνατοί αλγόριθμοι και δομές γραμμένοι με τον πιο γενικό τρόπο  instantiation ανάλογα με την περίπτωση κατά τη μεταγλώττιση Δομές δεδομένων vector, list, deque, set, map, stack, … Δομές δεδομένων vector, list, deque, set, map, stack, … Αλγόριθμοι for_each, sort, binary_search, find, count, … Αλγόριθμοι for_each, sort, binary_search, find, count, … Iterators input, output, random access, bidirectional, … Iterators input, output, random access, bidirectional, …

Παράδειγμα: πλήθος εμφανίσεων μιας τιμής σε ένα vector vector v; vector ::iterator b = v.begin(), e = v.end(); long c = count( 4); template long count(Iter first, Iter last, const T& value) { long ret=0; while ( first != last ) if (*first++ == value) ++ret; return ret; } b, e,  γενικευμένη υλοποίηση χωρίς να υστερεί σε απόδοση

Function objects (“Functors”)  Κλάσεις στις οποίες έχει υπερφορτωθεί ο τελεστής ()  Έχουν την λειτουργικότητα συναρτήσεων – στην ουσία είναι σαν δείκτες σε συναρτήσεις – επιπλέον πλεονεκτήματα (π.χ. αποθήκευση state)  Σε αυτά στηρίζεται η λειτουργία των TBBs – παράλληλα αλγοριθμικά μοτίβα υλοποιημένα σαν template functions – κώδικας χρήστη υλοποιημένος σαν function object

Παράδειγμα functor 56 template void ForEach( I lower, I upper, const Functor& f ) { for ( I i=lower; i<upper; ++i ) f(i); } Template function for iteration class Accumulate { float& acc; float* src; public: Accumulate(float& acc_, float* src_) : acc(acc_), src(src_) (0) {} void operator()( int i ) { acc += src[i];} }; Functor float a[4] = {1,3,9,27}; float sum = 0.0; Accumulate A(sum,a); ForEach( 0, 4, A ); cout << sum; Pass functor to template function.

Παραλληλοποίηση for-loop  tbb::parallel_for – χωρίζει τον αρχικό χώρο επαναλήψεων σε μικρότερα κομμάτια και τα εκτελεί παράλληλα – template function  1 ο βήμα: χρειάζεται να δώσουμε μια περιγραφή για το τι δουλειά θα γίνεται σε έναν οποιονδήποτε υποχώρο επαναλήψεων του loop – γράφουμε το σώμα του loop στον operator() ενός function object – ο operator() είναι παραμετροποιημένος με βάση έναν υποχώρο class ApplyFoo { float *const my_a; public: ApplyFoo( float *a ) : my_a(a) {} void operator()( const blocked_range & r ) const { float *a = my_a; for ( int i=r.begin(); i!=r.end(); ++i ) Foo(a[i]); } blocked_range : κλάση που εκφράζει 1D γραμμικό range πάνω στον τύπο Τ

Παραλληλοποίηση for-loop  2 ο βήμα: κλήση parallel_for  η parallel_for αναλαμβάνει: – να διασπάσει το αρχικό range σε πολλά μικρότερα – να εφαρμόσει παράλληλα το function object σε καθένα από αυτά float a[100]; parallel_for( blocked_range (0,100), ApplyFoo(a) ); δημιουργία (ανώνυμου) αντικειμένου για την περιγραφή του αρχικού χώρου επαναλήψεων δημιουργία function object

Δήλωση parallel_for  Απαιτήσεις για το Body B  Απαιτήσεις για το Range R template void parallel_for(const Range& R, const Body& B ); R(const R&)Copy a range R::~R()Destroy a range bool R::empty() constIs range empty? bool R::is_divisible() constCan range be split? R::R (R& r, split)Split r into two subranges B::B( const F& )Copy constructor B::~B()Destructor void B::operator() (Range& subrange) const Apply B to subrange η βιβλιοθήκη παρέχει τις κλάσεις blocked_range, blocked_range2d, blocked_range3d

Πιθανές σειρές εκτέλεσης των tasks Depth-first - Απαιτεί λίγο χώρο - Καλή τοπικότητα αναφορών - Μηδενικός παραλληλισμός Breadth-first - Απαιτεί πολύ χώρο - Κακή τοπικότητα αναφορών - Μέγιστος παραλληλισμός

Work depth-first, steal breadth-first  Εξισορροπεί καλύτερα τις προηγούμενες απαιτήσεις L1 L2 victim thread Δεύτερη καλύτερη επιλογή Το κλέψιμο από την κορυφή εξασφαλίζει: - μεγάλο κομμάτι δουλειάς → καλή περαιτέρω κατανομή φορτίου - LRU δεδομένα του θύματος στον «κλέφτη», τα MRU παραμένουν στο «θύμα»