Παράλληλος Προγραμματισμός με OpenCL Συστήματα Παράλληλης Επεξεργασίας 9ο εξάμηνο, ΣΗΜΜΥ Εργαστήριο Υπολογιστικών Συστημάτων (CSLab) Δεκέμβριος 2017
1 Γενικά για OpenCL 2 Platform Model 3 Execution Model 4 Memory Model 5 Προγραμματισμός με OpenCL 6 Χρήσιμα links 2 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
1 Γενικά για OpenCL 2 Platform Model 3 Execution Model 4 Memory Model 5 Προγραμματισμός με OpenCL 6 Χρήσιμα links 3 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
It s a... Heterogeneous World Ένα συγχρονο σύστημα μπορεί να περιλαμβάνει: Μία ή περισσότερες CPUs Μία ή περισσότερες GPUs Άλλους επιταχυντές (π.χ. DSPs) 4 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Τι είναι η OpenCL; Open Computing Language Ανοιχτό πρότυπο για προγραμματισμό σε ετερογενή συστήματα CPUs, GPUs, DSPs, FPGAs κ.λπ. Ορίζει μια γλώσσα προγραμματισμού Ορίζει διεπαφή (API) για την εκτέλεση προγραμμάτων σε συσκευές Δεν ορίζει υλοποίηση! Σχεδιαστικοί στόχοι Αποτελεσματική χρήση όλων των υπολογιστικών πόρων ενός ετερογενούς συστήματος Διευκολύνση του παράλληλου προγραμματισμού σε ένα τέτοιο σύστημα Γλώσσα βασισμένη σε C99 Κρύβει λεπτομέρειες της αρχιτεκτονικής από τον προγραμματιστή Υποστηρίζει data και task parallelism Portability Ο ίδιος κώδικας μπορεί να τρέξει σε διαφορετικές αρχιτεκτονικές 5 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
1 Γενικά για OpenCL 2 Platform Model 3 Execution Model 4 Memory Model 5 Προγραμματισμός με OpenCL 6 Χρήσιμα links 6 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Platform Model Πώς η OpenCL βλέπει το υλικό Πηγή: OpenCL Specification 7 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Platform Model Αντιστοίχιση σε CPUs Host = CPU Compute Device = CPU Compute Unit = Core Processing Element = Core or SIMD lane 8 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Platform Model Αντιστοίχιση σε NVIDIA GPUs Host = CPU Compute Device = GPU Compute Unit = CUDA Streaming Multiprocessor Processing Element = CUDA Streaming Processor 9 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
1 Γενικά για OpenCL 2 Platform Model 3 Execution Model 4 Memory Model 5 Προγραμματισμός με OpenCL 6 Χρήσιμα links 10 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Execution Model Ένα πρόγραμμα σε OpenCL αποτελείται από: Kernels Host Code Η εκτέλεση ενός kernel Εκκινείται από τον host μέσα σε ένα καλώς ορισμένο execution context O host δημιουργεί και διαχειρίζεται το execution context μέσω του OpenCL API Περιλαμβάνει τις συσκευές, τις μνήμες τους και ένα command queue ανά συσκευή Η αλληλεπίδραση του host με ένα device γίνεται μέσα από ένα command queue kernel, memory, synchronization commands in-order ή out-of-order εκτέλεση των commands Πραγματοποιείται από work-items τα οποία συνθέτουν τα work-groups work-item = kernel instance Δημιουργούνται τόσα work-items όσα τα σημεία ενός Ν-διάστατου χώρου που ορίζουμε προγραμματιστικά (computation domain) 11 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Execution Model NDRange - Ν-διάστατος χώρος Πηγή: OpenCL Specification To N μπορεί να είναι 1, 2 ή 3 Ο NDRange χώρος οργανώνεται σε work-groups τα οποία μπορούν να έχουν Ν διαστάσεις Οι διαστάσεις των work-groups μπορεί να είναι διαφορετικές μεταξύ τους Μία υλοποίηση της OpenCL μπορεί να οργανώσει περαιτέρω τα work-groups σε subgroups (π.χ. warps σε NVIDIA GPUs) 12 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
1 Γενικά για OpenCL 2 Platform Model 3 Execution Model 4 Memory Model 5 Προγραμματισμός με OpenCL 6 Χρήσιμα links 13 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Memory Model Μοντέλο μοιραζόμενης μνήμης με χαλαρή συνέπεια μνήμης (consistency) Πολλαπλές διακριτές περιοχές διευθύνσεων (address spaces) Private - private στο work-item Local - local στο work-group Global - πρόσβαση από όλα τα work-items σε όλα τα work-groups Constant - read-only global space Κάθε υλοποίηση αντιστοιχίζει αυτήν την ιεραρχία στις διαθέσιμες φυσικές μνήμες της συσκευής Πηγή: OpenCL Specification 14 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Memory Model Συνέπεια μνήμης Η OpenCL χρησιμοποιεί ενά μοντέλο μνήμης με χαλαρούς κανόνες συνέπειας Η κατάσταση μνήμης ενός work-item δεν είναι εγγυημένα ορατή από άλλα work-items Υπάρχει συνέπεια στα load/store operations εντός του work-item Η Local μνήμη έχει συνέπεια μεταξύ διαφορετικών work-items του ίδιου work-group όταν συναντάται barrier Η Global μνήμη έχει συνέπεια εντός ενός work-group όταν συναντάται barrier, αλλά όχι μεταξύ διαφορετικών work-groups 15 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
1 Γενικά για OpenCL 2 Platform Model 3 Execution Model 4 Memory Model 5 Προγραμματισμός με OpenCL 6 Χρήσιμα links 16 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
OpenCL Framework Τι περιλαμβάνει; Μία υπολοποίηση της OpenCL περιλαμβάνει: Platform layer Πληροφορίες συστήματος και δημιουργία OpenCL execution contexts Μεταγλωττιστή για OpenCL C Βιβλιοθήκη χρόνου εκτέλεσης Διαχείριση μνήμης και εκτέλεση υπολογισμών στις συσκευές 17 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
OpenCL Framework Platform layer Πληροφορίες συστήματος και συσκευών clgetplatformids(): λίστα από διαθέσιμες υλοποιήσεις της OpenCL στο σύστημα (π.χ. Intel, AMD, NVIDIA) clgetplatforminfo(): έκδοση OpenCL, όνομα, προμηθευτής clgetdeviceids(): λίστα από συσκευές στο σύστημα clgetdeviceinfo(): τύπος και δυνατότητες συσκευών Δημιουργία ενός OpenCL context για μία ή περισσότερες συσκευές clcreatecontext() cl_device_id: αναγνωριστικά συσκευών cl_mem: μνήμη η οποία είναι κοινή για αυτές τις συσκευές cl_program: κώδικας ο οποίος είναι κοινός για αυτές τις συσκευές cl_command_queue: ουρές για υποβολή εργασιών στις συσκευές 18 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
OpenCL Framework Platform layer - Παράδειγμα χρήσης / / Get p l a t f o r m ID c l _ p l a t f o r m _ i d p l a t f o r m ; c l G e t P l a t f o r m I D s ( 1, &platform, NULL ) ; / / Get the f i r s t GPU device c l _ d e v i c e _ i d device ; c l G e t D e v i c e I D s ( platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL ) ; / / Create an OpenCL c o n t e x t f o r t h i s GPU c l _ c o n t e x t c o n t e x t ; c o n t e x t = c l C r e a t e C o n t e x t ( NULL, 1, &device, NULL, NULL, NULL ) ; 19 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
OpenCL Framework Διαδικασία μεταγλώττισης και εκτέλεσης Αρχεία πηγαίου κώδικα με κατάληξη.c για τον κώδικα του host.cl για κώδικα συσκευής 20 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
OpenCL Framework OpenCL C Επέκταση της ISO C99 με επιπλέον τύπους και προσδιοριστές Προσθήκες: Work-items και work-groups Vector types Συγχρονισμός Built-in συναρτήσεις για μαθηματικές συναρτήσεις, διαχείριση εικόνων και work-items... Δεν υποστηρίζονται: Function pointers Bit-fields Variable-lengh arrays Αναδρομή... 21 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
OpenCL C Προσδιοριστές συναρτήσεων και μεταβλητών Προσδιοριστές συναρτήσεων kernel (or kernel ) Εκτελείται στην συσκευή Μπορεί να κληθεί από κώδικα του host και της συσκευής Προσδιοριστές μεταβλητών global ( or global) Βρίσκεται στην global μνήμη Προσβάσιμη από όλα τα work-items local ( or local ) Βρίσκεται στην local μνήμη Προσβάσιμη από όλα τα work-items ενός work-group constant (or constant) Βρίσκεται στην global μνήμη Προσβάσιμη μόνο για ανάγνωση από όλα τα work-items private (or private ) Βρίσκεται στην private μνήμη Προσβάσιμη από ένα μοναδικό work-item 22 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
OpenCL C Συγχρονισμός Built-in συναρτήσεις για επιβολή σειράς σε memory operations και για τον συγχρονισμό εκτέλεσης μεταξύ work-items mem_fence(clk_local_mem_fence και/ή CLK_GLOBAL_MEM_FENCE) περιμένει μέχρι όλα τα reads/writes στην local και/ή global μνήμη που έγιναν από το work-item πριν από το mem_fence() να γίνουν ορατά στα υπόλοιπα work-items του work-group barrier(clk_local_mem_fence και/ή CLK_GLOBAL_MEM_FENCE) περιμένει μέχρι όλα τα work-items να φτάσουν το barrier() και καλεί την mem_fence() 23 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
OpenCL Framework Βιβλιοθήκη χρόνου εκτέλεσης Linking Συναρτήσεις επικοινωνίας με την συσκευή Συναρτήσεις διαχείρισης μεταγλώττισης και εκτέλεσης κώδικα συσκευής Συναρτήσεις διαχείρισης μνήμης Συναρτήσεις διαχείρισης σφαλμάτων Συναρτήσεις δημιουργίας και διαχείρισης γεγονότων Σύνδεση με την βιβλιοθήκη OpenCL, lopencl 24 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Βιβλιοθήκη χρόνου εκτέλεσης Επικοινωνία με την συσκευή Η επικοινωνία γίνεται μέσα από commands που υποβάλλονται σε command queues clcreatecommandqueue(): δημιουργία ουράς για μία συσκευή clenqueue*(): υποβολή ενός command στη ουρά Μπορεί να ορίσουμε πολλές ουρές ανά συσκευή Δύο τρόποι εκτέλεσης των commands στις ουρές in-order: ένα command εκτελείται αφού ολοκληρωθεί η εκτέλεση αλλά και τα memory writes του προηγούμενου out-of-order: δεν υπάρχει καμία εγγύηση για τη σειρά ολοκλήρωσης 25 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Βιβλιοθήκη χρόνου εκτέλεσης Μεταγλώττιση κώδικα συσκευής Ένα αντικείμενο cl_program περιγράφει κάποιον πηγαίο κώδικα (με πολλά ενδεχομένως device kernels) και την τελευταία του επιτυχημένη μεταγλώττιση clcreateprogramwithsource() clbuildprogram() Ένα αντικείμενο cl_kernel περιέχει τις τιμές των ορισμάτων ενός kernel όταν αυτός καλείται clcreatekernel() clsetkernelarg() 26 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Βιβλιοθήκη χρόνου εκτέλεσης Μεταγλώττιση κώδικα συσκευής - Παράδειγμα / / B u i l d program o b j e c t and s e t up k e r n e l arguments const char * source = k e r n e l void dp_mul ( g l o b a l const f l o a t * a, \ n g l o b a l const f l o a t *b, \ n g l o b a l f l o a t * c, \ n i n t N ) \ n { \ n i n t i d = g e t _ g l o b a l _ i d ( 0 ) ; \ n i f ( i d < N ) \ n c [ i d ] = a [ i d ] * b [ i d ] ; \ n } \ n ; cl_ program program = clcreateprogramwithsource ( context, 1, &source, NULL, NULL ) ; c l B u i l d P r o g r a m ( program, 0, NULL, NULL, NULL, NULL ) ; c l _ k e r n e l k e r n e l = c l C r e a t e K e r n e l ( program, dp_mul, NULL ) ; c l S e t K e r n e l A r g ( k e r n e l, 0, s i z e o f ( cl_mem ), ( void *)& d _ b u f f e r ) ; c l S e t K e r n e l A r g ( k e r n e l, 1, s i z e o f ( i n t ), ( void *)&N ) ; 27 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Βιβλιοθήκη χρόνου εκτέλεσης Εκτέλεση κώδικα συσκευής H εκτέλεση ενός kernel γίνεται πάνω σε ένα NDRange H εκτέλεση ενός kernel ορίζεται ως ένα command το οποίο πρέπει να υποβληθεί στη ουρά της συσκευής clenqueuendrangekernel() / / Set number of work items i n a work group s i z e _ t l o c a l W o r k S i z e = 2 5 6 ; i n t numworkgroups = ( N + l o c a l W o r k S i z e 1 ) / l o c a l W o r k S i z e ; s i z e _ t g l o b a l W o r k S i z e = numworkgroups * l o c a l W o r k S i z e ; clenqueuendrangekernel ( cmd_queue, k e r n e l, 1, NULL, & globalworksize, & l o c a l W o r k S i z e, 0, NULL, NULL ) ; 28 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Βιβλιοθήκη χρόνου εκτέλεσης Διαχείριση μνήμης - Παράδειγμα / / Create b u f f e r s on host and device s i z e _ t s i z e = 100000 * s i z e o f ( i n t ) ; i n t * h _ b u f f e r = ( i n t * ) malloc ( s i z e ) ; cl_mem d _ b u f f e r = c l C r e a t e B u f f e r ( context, CL_MEM_READ_WRITE, s i z e, NULL, NULL ) ;... / / W r i t e to b u f f e r o b j e c t from host memory c l E n q u e u e W r i t e B u f f e r ( cmd_queue, d_buffer, CL_FALSE, 0, s i z e, h_ buffer, 0, NULL, NULL ) ;... / / Read from b u f f e r o b j e c t to host memory clenqueuereadbuffer ( cmd_queue, d_ buffer, CL_TRUE, 0, s i z e, h_buffer, 0, NULL, NULL ) ; 29 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
OpenCL C Κώδικας συσκευής Άθροισμα διανυσμάτων Συναρτήσεις προσδιορισμού του ID ενός work-item μέσα στο NDRange get_work_dim(): αριθμός διαστάσεων του χώρου (1, 2 ή 3) get_global_size(uint dimindx): ο αριθμός των work-items στη διάσταση dimindx get_local_id(uint dimindx): τοπικό id ενός work-item εντός του work-group στη διάσταση dimindx get_global_id(uint dimindx): καθολικό id ενός work-item στη διάσταση dimindx k e r n e l void vec_add ( const g l o b a l f l o a t * a, const g l o b a l f l o a t *b, g l o b a l f l o a t * c, i n t N ) { i n t t i d = g e t _ l o c a l _ s i z e ( 0 ) * get_group_id ( 0 ) + g e t _ l o c a l _ i d ( 0 ) ; i f ( t i d < N ) c [ t i d ] = a [ t i d ] + b [ t i d ] ; } 30 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
OpenCL vs CUDA Κώδικας συσκευής Άθροισμα διανυσμάτων OpenCL k e r n e l void vec_add ( const g l o b a l f l o a t * a, const g l o b a l f l o a t *b, g l o b a l f l o a t * c, i n t N ) { i n t t i d = g e t _ l o c a l _ s i z e ( 0 ) * get_group_id ( 0 ) + g e t _ l o c a l _ i d ( 0 ) ; i f ( t i d < N ) c [ t i d ] = a [ t i d ] + b [ t i d ] ; } CUDA global void vec_add ( const f l o a t * a, const f l o a t *b, f l o a t * c, i n t N ) { i n t t i d = blockdim. x * b l o c k I d x. x + t h r e a d I d x. x ; i f ( t i d < N ) c [ t i d ] = a [ t i d ] + b [ t i d ] ; } 31 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
OpenCL vendor support 32 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
1 Γενικά για OpenCL 2 Platform Model 3 Execution Model 4 Memory Model 5 Προγραμματισμός με OpenCL 6 Χρήσιμα links 33 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Χρήσιμα links http://www.khronos.org/opencl 34 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας
Συζήτηση Ερωτήσεις 35 11 / 2017 Συστήματα Παράλληλης Επεξεργασίας