Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Este documento especifica uma coleção de diretivas de compilador, funções de biblioteca e variáveis de ambiente que você pode usar para especificar paralelismo de memória compartilhada em programas C e C++. A funcionalidade descrita neste documento é coletivamente conhecida como OpenMP C/C++ Application Program Interface (API). O objetivo desta especificação é fornecer um modelo para programação paralela que permita que um programa seja portátil entre arquiteturas de memória compartilhada de diferentes fornecedores. Compiladores de muitos fornecedores suportam a API OpenMP C/C++. Mais informações sobre o OpenMP, incluindo o OpenMP Fortran Application Program Interface, podem ser encontradas no seguinte site:
As diretivas, funções de biblioteca e variáveis de ambiente definidas neste documento permitem criar e gerenciar programas paralelos, permitindo a portabilidade. As diretivas estendem o modelo de programação sequencial C e C++ com construções SPMD (single program multiple data), construções de compartilhamento de trabalho e construções de sincronização. Apoiam igualmente a partilha e a privatização dos dados. Os compiladores que suportam a API OpenMP C e C++ incluem uma opção de linha de comando para o compilador que ativa e permite a interpretação de todas as diretivas do compilador OpenMP.
1.1 Âmbito de aplicação
Esta especificação abrange apenas a paralelização direcionada ao usuário, na qual você define explicitamente quais ações o compilador e o sistema de tempo de execução tomam para executar o programa em paralelo. As implementações OpenMP em C e C++ não são obrigadas a verificar dependências, conflitos, deadlocks, condições de concorrência ou outros problemas que resultem na execução incorreta do programa. Você é responsável por garantir que o aplicativo que usa as construções da API OpenMP C e C++ seja executado corretamente. A paralelização automática gerada pelo compilador e as diretivas para o compilador para auxiliar essa paralelização não são abordadas neste documento.
1.2 Definição dos termos
Os seguintes termos são usados neste documento:
barreira
Um ponto de sincronização que todos os threads de uma equipa devem atingir. Cada thread espera até que todos os threads da equipe cheguem a este ponto. Existem obstáculos explícitos identificados pelas diretivas e obstáculos implícitos criados pela aplicação.
construir
Uma construção é uma declaração. Consiste numa diretiva, seguida de um bloco estruturado. Algumas diretivas não fazem parte de uma construção. (Ver diretiva openmp no apêndice C).
directiva
Um C ou C++
#pragmaseguido peloompidentificador, outro texto e uma nova linha. A diretiva especifica o comportamento do programa.extensão dinâmica
Todas as instruções na extensão lexical, mais qualquer instrução dentro de uma função que é executada como resultado da execução de instruções dentro da extensão lexical. Uma extensão dinâmica também é referida como uma região.
extensão lexical
Declarações mantidas lexicamente dentro de um bloco estruturado.
thread mestre
O thread que cria uma equipe quando uma região paralela é inserida.
região paralela
Instruções que se associam a uma construção paralela OpenMP e podem ser executadas por muitos threads.
privado
Uma variável privada nomeia um bloco de armazenamento que é exclusivo para o thread que faz a referência. Há várias maneiras de especificar que uma variável é privada: uma definição dentro de uma região paralela, uma
threadprivatediretiva, umaprivate,firstprivate,lastprivate, oureductioncláusula, ou o uso da variável como umaforvariável de controle de ciclo em umforciclo imediatamente após umaforouparallel fordiretiva.região
Uma extensão dinâmica.
região de série
Instruções executadas apenas pelo thread mestre fora da extensão dinâmica de qualquer região paralela.
serializar
Para executar uma construção paralela com:
uma equipe de threads que consiste em apenas um único thread (que é o thread mestre para essa construção paralela),
ordem de execução sequencial para as instruções dentro do bloco estruturado (a mesma ordem que se o bloco não fizesse parte de uma construção paralela), e
nenhum efeito sobre o valor retornado por
omp_in_parallel()(exceto os efeitos de quaisquer construções paralelas aninhadas).
compartilhada
Uma variável compartilhada nomeia um único bloco de armazenamento. Todos os threads de uma equipe que acessam essa variável também acessam esse único bloco de armazenamento.
bloco estruturado
Um bloco estruturado é uma instrução (única ou composta) que tem uma única entrada e uma única saída. Se houver uma transição para dentro ou fora de uma declaração, essa declaração é um bloco estruturado. (Esta regra inclui uma chamada para
longjmp(3C) ou a utilização dethrow, embora seja permitida uma chamada paraexit.) Se sua execução sempre começa na abertura{e sempre termina no fechamento}, uma instrução composta é um bloco estruturado. Uma instrução de expressão, instrução de seleção, instrução de iteração outrybloco é um bloco estruturado se a instrução composta correspondente, obtida ao encerrá-la em{e}, for um bloco estruturado. Uma instrução de salto, uma instrução rotulada ou uma instrução de declaração não é um bloco estruturado.equipa
Um ou mais threads cooperando na execução de uma construção.
conversa
Uma entidade de execução com um fluxo serial de controle, um conjunto de variáveis privadas e acesso a variáveis compartilhadas.
variável
Um identificador, opcionalmente qualificado por nomes de namespace, que nomeia um objeto.
1.3 Modelo de execução
OpenMP usa o modelo fork-join de execução paralela. Embora esse modelo de junção de bifurcação possa ser útil para resolver vários problemas, ele é adaptado para aplicativos baseados em grandes arrays. OpenMP destina-se a suportar programas que executam corretamente tanto como programas paralelos (muitos threads de execução e uma biblioteca de suporte OpenMP completa). É também para programas que são executados corretamente como programas sequenciais (com diretivas ignoradas e uma simples biblioteca de 'stubs' OpenMP). No entanto, é possível e permitido desenvolver um programa que não se comporta corretamente quando executado sequencialmente. Além disso, diferentes graus de paralelismo podem resultar em resultados numéricos diferentes devido a mudanças na associação de operações numéricas. Por exemplo, uma redução de adição em série pode ter um padrão diferente de associações de adição do que uma redução paralela. Estas diferentes associações podem alterar os resultados da adição de vírgula flutuante.
Um programa escrito com a API OpenMP C/C++ começa a execução como um único thread de execução chamado thread mestre. O thread mestre é executado em uma região serial até que a primeira construção paralela seja encontrada. Na API OpenMP C/C++, a parallel diretiva constitui uma construção paralela. Quando uma construção paralela é encontrada, o thread mestre cria uma equipe de threads e o mestre se torna mestre da equipe. Cada thread na equipe executa as instruções na extensão dinâmica de uma região paralela, exceto para as construções de compartilhamento de trabalho. Todos os threads na equipe devem encontrar construções de compartilhamento de trabalho na mesma ordem, e um ou mais dos threads executam as instruções dentro do bloco estruturado associado. A barreira implícita no final de uma construção de compartilhamento de tarefas sem uma nowait cláusula é executada por todos os threads da equipe.
Se um thread modifica um objeto compartilhado, ele afeta não apenas seu próprio ambiente de execução, mas também os dos outros threads no programa. A modificação é garantida para ser completa, do ponto de vista de outro thread, no próximo ponto de sequência (conforme definido na linguagem base) apenas se o objeto for declarado como volátil. Caso contrário, a modificação é garantida para ser concluída após o primeiro thread de modificação. Os outros threads então (ou simultaneamente) veem uma flush diretiva que especifica o objeto (implícita ou explicitamente). Quando as flush diretivas que estão implícitas por outras diretivas OpenMP não garantem a ordenação correta dos efeitos colaterais, é responsabilidade do programador fornecer diretivas adicionais e explícitas flush .
Após a conclusão da construção paralela, os threads na equipe sincronizam em uma barreira implícita e apenas o thread mestre continua a execução. Qualquer número de construções paralelas pode ser especificado em um único programa. Como resultado, um programa pode bifurcar e juntar-se muitas vezes durante a execução.
A API OpenMP C/C++ permite que os programadores usem diretivas em funções chamadas de dentro de construções paralelas. As diretivas que não aparecem na extensão lexical de uma construção paralela, mas podem estar na extensão dinâmica, são chamadas de diretivas órfãs . Com diretivas órfãs, os programadores podem executar grandes porções do seu programa em paralelo, com apenas alterações mínimas no programa sequencial. Com essa funcionalidade, você pode codificar construções paralelas nos níveis superiores da árvore de chamadas do programa e usar diretivas para controlar a execução em qualquer uma das funções chamadas.
Chamadas não sincronizadas para funções de saída C e C++ que gravam no mesmo arquivo podem resultar em saída na qual os dados gravados por threads diferentes aparecem em ordem não determinística. Da mesma forma, chamadas não sincronizadas para funções de entrada que leem do mesmo arquivo podem ler dados em ordem não determinística. O uso não sincronizado de E/S, de modo que cada thread acesse um arquivo diferente, produz os mesmos resultados que a execução serial das funções de E/S.
1.4 Conformidade
Uma implementação da API OpenMP C/C++ é compatível com OpenMP se reconhecer e preservar a semântica de todos os elementos desta especificação, conforme estabelecido nos Capítulos 1, 2, 3, 4 e Apêndice C. Os apêndices A, B, D, E e F são apenas para fins informativos e não fazem parte da especificação. As implementações que incluem apenas um subconjunto da API não são compatíveis com OpenMP.
A API OpenMP C e C++ é uma extensão para a linguagem base que é suportada por uma implementação. Se a linguagem base não suportar uma construção de linguagem ou extensão que aparece neste documento, a implementação OpenMP não é necessária para suportá-la.
Todas as funções padrão da biblioteca C e C++ e funções internas (ou seja, funções das quais o compilador tem conhecimento específico) devem ser thread-safe. O uso não sincronizado de funções thread-safe por diferentes threads dentro de uma região paralela não produz um comportamento indefinido. No entanto, o comportamento pode não ser o mesmo que em uma região sequencial. (Uma função de geração de números aleatórios é um exemplo.)
A API C/C++ do OpenMP especifica que determinado comportamento é definido pela implementação. Uma implementação OpenMP em conformidade é necessária para definir e documentar seu comportamento nesses casos. Para obter uma lista de comportamentos definidos pela implementação, consulte o apêndice E.
1.5 Referências normativas
ISO/IEC 9899:1999, Tecnologia da Informação - Linguagens de Programação - C. Esta especificação OpenMP API refere-se à ISO/IEC 9899:1999 como C99.
ISO/IEC 9899:1990, Tecnologia da Informação - Linguagens de Programação - C. Esta especificação OpenMP API refere-se à ISO/IEC 9899:1990 como C90.
ISO/IEC 14882:1998, Tecnologia da Informação - Linguagens de Programação - C++. Esta especificação OpenMP API refere-se à ISO/IEC 14882:1998 como C++.
Quando esta especificação da API OpenMP se refere a C, é feita referência à linguagem base suportada pela implementação.