b'\n_START_ARTICLE_\nOpenMP\n_START_SECTION_\nIntroducci\xc3\xb3\n_START_PARAGRAPH_\nOpenMP \xc3\xa9s una implementaci\xc3\xb3 de multithreading, un m\xc3\xa8tode de paral\xc2\xb7lelitzaci\xc3\xb3 pel qual el "thread" (fil, en angl\xc3\xa8s) mestre (una s\xc3\xa8rie d\'instruccions executades consecutivament) es "bifurca" en un nombre determinat de "threads" esclaus i la tasca es divideix entre ells. Els threads llavors s\'executen concurrentment, amb l\'entorn d\'execuci\xc3\xb3 ubicant els threads a diferents processadors._NEWLINE_La secci\xc3\xb3 de codi que es vol que s\'executi en paral\xc2\xb7lel \xc3\xa9s marcada corresponentment, amb una directiva de preprocessador que far\xc3\xa0 que els threads es formin abans que la secci\xc3\xb3 sigui executada. Cada thread t\xc3\xa9 un "id" (identificador) associat que pot ser obtingut fent servir una funci\xc3\xb3 (anomenada omp_get_thread_num() a C/C++ i OMP_GET_THREAD_NUM() a Fortran). L\'id de thread \xc3\xa9s un enter, i el thread mestre t\xc3\xa9 una id de "0". Despr\xc3\xa9s de l\'execuci\xc3\xb3 del codi paral\xc2\xb7lelitzat, els threads s\'"uneixen" de nou al thread mestre, que continua endavant fins al final del programa._NEWLINE_Per defecte, cada thread executa la secci\xc3\xb3 de codi paral\xc2\xb7lelitzada independentment. Es poden fer servir "construccions de compartici\xc3\xb3 de treball" per a  dividir una tasca entre els threads de forma que cada thread executi la part de codi que t\xc3\xa9 assignada. Fent servir OpenMP d\'aquesta forma es pot aconseguir tant el paral\xc2\xb7lelisme de tasques com el paral\xc2\xb7lelisme de dades._NEWLINE_L\'entorn d\'execuci\xc3\xb3 assigna els threads a processadors depenent de l\'\xc3\xbas, la c\xc3\xa0rrega de la m\xc3\xa0quina i altres factors. El nombre de threads pot ser assignat per l\'entorn d\'execuci\xc3\xb3 basant-se en variables d\'entorn o en codi fent servir funcions. Les funcions OpenMP estan incloses en un fitxer de cap\xc3\xa7alera amb el nom "omp.h" a C/C++.\n_START_SECTION_\nDirectives de compilaci\xc3\xb3\n_START_PARAGRAPH_\nA OpenMP es troben una s\xc3\xa8rie de construccions de control i d\'atributs de dades, que s\'estenen al llenguatge base (F77, f90, C i C++). Els compiladors, per defecte, ometen aquestes directives OpenMP si no s\'activen mitjan\xc3\xa7ant un flag "-mp" o "-fopenmp".\n_START_SECTION_\nBiblioteca i variables d\'entorn\n_START_PARAGRAPH_\nOpenMP disposa d\'un conjunt de funcions per controlar par\xc3\xa0metres incloses a la llibreria de C "omp.h". Un exemple seria la definici\xc3\xb3 del n\xc3\xbamero de threads mitjan\xc3\xa7ant call omp_set_num_threads(64). Per una altra banda, disposa de variables d\'entorn que permeten controlar par\xc3\xa0metres de forma diferent, com per exemple setenv OMP_NUM_THREADS(8).\n_START_SECTION_\nElements principals\n_START_PARAGRAPH_\nEls elements principals d\'OpenMP s\xc3\xb3n directives per a la creaci\xc3\xb3 de threads, distribuci\xc3\xb3 de treball, gesti\xc3\xb3 de dades en l\'entorn, sincronitzaci\xc3\xb3 de threads, rutines d\'execuci\xc3\xb3 a nivell d\'usuari i variables d\'entorn. Aquestes directives a C/C++ s\'anomenen #pragmas.\n_START_SECTION_\nDirectives vectorials\n_START_PARAGRAPH_\nEn un primer nivell, podem diferenciar les directives SIMD o vectorial, destinades a paral\xc2\xb7lelisme a nivell de dades. La directiva #pragma omp simd, indica al compilador que el bucle seg\xc3\xbcent es vectoritzable._NEWLINE_Segons la versi\xc3\xb3 del compilador apuesta directiva pot ser ignorada, que el processador trobi errades en depend\xc3\xa8ncies de dades que impedeixin la paral\xc2\xb7lelitzaci\xc3\xb3 d\'aquest o b\xc3\xa9 que utilitzi aquesta directiva com a pista per a utilitzar instruccions vectorials. La directiva #pragma omp declare simd indica al compilador que ha de generar una versi\xc3\xb3 SIMD d\'una funci\xc3\xb3 que podr\xc3\xa0 ser cridada des d\'un bucle vectoritzat. Per tant, la funci\xc3\xb3 declarada amb aquesta directiva podr\xc3\xa0 tamb\xc3\xa9 ser executada sense necessitat d\'aplicar paral\xc2\xb7lelisme de dades._NEWLINE_Tot i que no ho indiquem expl\xc3\xadcitament, el compilador analitza el codi i tracta de vectoritzar els bucles de forma autom\xc3\xa0tica (sempre que s\'indiqui al compilador un nivell d\'optimitzaci\xc3\xb3 adequat mitjan\xc3\xa7ant clags com -O3 o Ofast). Per comprobar que realment el compilador ha vectoritzat un bucle, podem analitzar el codi m\xc3\xa0quina on descobrirem una "p" als mnem\xc3\xb2nics de les instruccions assembler, fet que confirma la utilitzaci\xc3\xb3 de paralel\xc2\xb7lisme SIMD.\n_START_SECTION_\nCreaci\xc3\xb3 de threads\n_START_PARAGRAPH_\nLa directiva #pragma omp parallel, basada en un model d\'execuci\xc3\xb3 FORK-JOIN que indica al compilador que el codi ser\xc3\xa0 executat per diferents threads, creant aix\xc3\xad una regi\xc3\xb3 paral\xc2\xb7lela. El thread encarregat de crear la resta s\'anomena master amb id 0. Un cop realitzat el fork, el compilador reparteix trossos d\'iteracions del seg\xc3\xbcent bucle als diferentes threads. Per defecte la variable d\'iteraci\xc3\xb3 del bucle \xc3\xa9s privada per a cada thread per\xc3\xb2 cal tenir en compte que si no s\'especifica el contrari, la resta de variables del codi sera compartides per tots els threads. Tamb\xc3\xa9 \xc3\xa9s destacable que totes les variables creades a l\'interior d\'aquesta construcci\xc3\xb3 seran creades per a cada thread.\n_START_SECTION_\nVariables d\'entorn\n_START_PARAGRAPH_\nLes variables d\'entorn s\xc3\xb3n un m\xc3\xa8tode per alterar les caracter\xc3\xadstiques d\'execuci\xc3\xb3 de les aplicacions que utilitzen OpenMP, com per exemple el n\xc3\xbamero de threads que es crearan per defecte a les regions paral\xc2\xb7leles mitjan\xc3\xa7ant OMP_NUM_THREADS.'