Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Fornece links para diretivas usadas na API OpenMP.
Visual C++ suporta as seguintes diretivas OpenMP.
Para a partilha paralela do trabalho:
| Directive | Description |
|---|---|
| parallel | Define uma região paralela, que é o código que será executado por vários threads em paralelo. |
| for | Faz com que o trabalho feito em um for loop dentro de uma região paralela seja dividido entre threads. |
| sections | Identifica as seções de código a serem divididas entre todos os threads. |
| single | Permite especificar que uma seção de código deve ser executada em um único thread, não necessariamente no thread principal. |
Para thread principal e sincronização:
| Directive | Description |
|---|---|
| master | Especifica que somente o thread principal deve executar uma seção do programa. |
| critical | Especifica que o código é executado apenas em um thread de cada vez. |
| barrier | Sincroniza todos os threads em uma equipe; Todos os fios param na barreira, até que todos os fios executem a barreira. |
| atomic | Especifica que um local de memória será atualizado atomicamente. |
| flush | Especifica que todos os threads têm a mesma exibição de memória para todos os objetos compartilhados. |
| ordered | Especifica que o código sob um loop paralelo for deve ser executado como um loop sequencial. |
Para ambiente de dados:
| Directive | Description |
|---|---|
| threadprivate | Especifica que uma variável é privada para um thread. |
atómico
Especifica que um local de memória que será atualizado atomicamente.
#pragma omp atomic
expression
Parameters
expression
A instrução que tem o lvalue, cujo local de memória você deseja proteger contra mais de uma gravação.
Remarks
A atomic diretiva não suporta cláusulas.
Para obter mais informações, consulte 2.6.4 Construção atômica.
Example
// omp_atomic.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
#define MAX 10
int main() {
int count = 0;
#pragma omp parallel num_threads(MAX)
{
#pragma omp atomic
count++;
}
printf_s("Number of threads: %d\n", count);
}
Number of threads: 10
barrier
Sincroniza todos os threads em uma equipe; Todos os fios param na barreira, até que todos os fios executem a barreira.
#pragma omp barrier
Remarks
A barrier diretiva não suporta cláusulas.
Para mais informações, ver 2.6.3 Diretiva de barreira.
Example
Para obter um exemplo de como usar barriero , consulte mestre.
crítico
Especifica que o código só deve ser executado em um thread de cada vez.
#pragma omp critical [(name)]
{
code_block
}
Parameters
name
(Opcional) Um nome para identificar o código crítico. O nome deve ser colocado entre parênteses.
Remarks
A critical diretiva não suporta cláusulas.
Para obter mais informações, consulte 2.6.2 construção crítica.
Example
// omp_critical.cpp
// compile with: /openmp
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int main()
{
int i;
int max;
int a[SIZE];
for (i = 0; i < SIZE; i++)
{
a[i] = rand();
printf_s("%d\n", a[i]);
}
max = a[0];
#pragma omp parallel for num_threads(4)
for (i = 1; i < SIZE; i++)
{
if (a[i] > max)
{
#pragma omp critical
{
// compare a[i] and max again because max
// could have been changed by another thread after
// the comparison outside the critical section
if (a[i] > max)
max = a[i];
}
}
}
printf_s("max = %d\n", max);
}
41
18467
6334
26500
19169
15724
11478
29358
26962
24464
max = 29358
libertar espaço
Especifica que todos os threads têm a mesma exibição de memória para todos os objetos compartilhados.
#pragma omp flush [(var)]
Parameters
var
(Opcional) Uma lista separada por vírgulas de variáveis que representam objetos que você deseja sincronizar. Se var não for especificado, toda a memória será liberada.
Remarks
A flush diretiva não suporta cláusulas.
Para obter mais informações, consulte 2.6.5 diretiva flush.
Example
// omp_flush.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
void read(int *data) {
printf_s("read data\n");
*data = 1;
}
void process(int *data) {
printf_s("process data\n");
(*data)++;
}
int main() {
int data;
int flag;
flag = 0;
#pragma omp parallel sections num_threads(2)
{
#pragma omp section
{
printf_s("Thread %d: ", omp_get_thread_num( ));
read(&data);
#pragma omp flush(data)
flag = 1;
#pragma omp flush(flag)
// Do more work.
}
#pragma omp section
{
while (!flag) {
#pragma omp flush(flag)
}
#pragma omp flush(data)
printf_s("Thread %d: ", omp_get_thread_num( ));
process(&data);
printf_s("data = %d\n", data);
}
}
}
Thread 0: read data
Thread 1: process data
data = 2
for
Faz com que o trabalho feito em um for loop dentro de uma região paralela seja dividido entre threads.
#pragma omp [parallel] for [clauses]
for_statement
Parameters
clauses
(Opcional) Zero ou mais cláusulas, consulte a secção Observações .
for_statement
Um for loop. O comportamento indefinido resultará se o código do for usuário no loop alterar a variável de índice.
Remarks
A for diretiva apoia as seguintes cláusulas:
Se parallel também for especificado, clauses pode ser qualquer cláusula aceita pelas parallelfor ou diretivas, exceto nowait.
Para obter mais informações, consulte 2.4.1 para construir.
Example
// omp_for.cpp
// compile with: /openmp
#include <stdio.h>
#include <math.h>
#include <omp.h>
#define NUM_THREADS 4
#define NUM_START 1
#define NUM_END 10
int main() {
int i, nRet = 0, nSum = 0, nStart = NUM_START, nEnd = NUM_END;
int nThreads = 0, nTmp = nStart + nEnd;
unsigned uTmp = (unsigned((abs(nStart - nEnd) + 1)) *
unsigned(abs(nTmp))) / 2;
int nSumCalc = uTmp;
if (nTmp < 0)
nSumCalc = -nSumCalc;
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel default(none) private(i) shared(nSum, nThreads, nStart, nEnd)
{
#pragma omp master
nThreads = omp_get_num_threads();
#pragma omp for
for (i=nStart; i<=nEnd; ++i) {
#pragma omp atomic
nSum += i;
}
}
if (nThreads == NUM_THREADS) {
printf_s("%d OpenMP threads were used.\n", NUM_THREADS);
nRet = 0;
}
else {
printf_s("Expected %d OpenMP threads, but %d were used.\n",
NUM_THREADS, nThreads);
nRet = 1;
}
if (nSum != nSumCalc) {
printf_s("The sum of %d through %d should be %d, "
"but %d was reported!\n",
NUM_START, NUM_END, nSumCalc, nSum);
nRet = 1;
}
else
printf_s("The sum of %d through %d is %d\n",
NUM_START, NUM_END, nSum);
}
4 OpenMP threads were used.
The sum of 1 through 10 is 55
master
Especifica que somente o thread principal deve executar uma seção do programa.
#pragma omp master
{
code_block
}
Remarks
A master diretiva não suporta cláusulas.
Para obter mais informações, consulte 2.6.1 master construct.
Para especificar que uma seção de código deve ser executada em um único thread, não necessariamente o thread principal, use a diretiva única .
Example
// compile with: /openmp
#include <omp.h>
#include <stdio.h>
int main( )
{
int a[5], i;
#pragma omp parallel
{
// Perform some computation.
#pragma omp for
for (i = 0; i < 5; i++)
a[i] = i * i;
// Print intermediate results.
#pragma omp master
for (i = 0; i < 5; i++)
printf_s("a[%d] = %d\n", i, a[i]);
// Wait.
#pragma omp barrier
// Continue with the computation.
#pragma omp for
for (i = 0; i < 5; i++)
a[i] += i;
}
}
a[0] = 0
a[1] = 1
a[2] = 4
a[3] = 9
a[4] = 16
ordered
Especifica que o código sob um loop paralelo for deve ser executado como um loop sequencial.
#pragma omp ordered
structured-block
Remarks
A ordered diretiva deve estar dentro da extensão dinâmica de um pró ou parallel for construção com uma ordered cláusula.
A ordered diretiva não suporta cláusulas.
Para obter mais informações, consulte 2.6.6 construção ordenada.
Example
// omp_ordered.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
static float a[1000], b[1000], c[1000];
void test(int first, int last)
{
#pragma omp for schedule(static) ordered
for (int i = first; i <= last; ++i) {
// Do something here.
if (i % 2)
{
#pragma omp ordered
printf_s("test() iteration %d\n", i);
}
}
}
void test2(int iter)
{
#pragma omp ordered
printf_s("test2() iteration %d\n", iter);
}
int main( )
{
int i;
#pragma omp parallel
{
test(1, 8);
#pragma omp for ordered
for (i = 0 ; i < 5 ; i++)
test2(i);
}
}
test() iteration 1
test() iteration 3
test() iteration 5
test() iteration 7
test2() iteration 0
test2() iteration 1
test2() iteration 2
test2() iteration 3
test2() iteration 4
parallel
Define uma região paralela, que é o código que será executado por vários threads em paralelo.
#pragma omp parallel [clauses]
{
code_block
}
Parameters
clauses
(Opcional) Zero ou mais cláusulas, consulte a secção Observações .
Remarks
A parallel diretiva apoia as seguintes cláusulas:
parallel também pode ser usado com as diretivas para e seções .
Para obter mais informações, consulte 2.3 Construção paralela.
Example
O exemplo a seguir mostra como definir o número de threads e definir uma região paralela. O número de threads é igual por padrão ao número de processadores lógicos na máquina. Por exemplo, se você tiver uma máquina com um processador físico que tenha o hyperthreading habilitado, ela terá dois processadores lógicos e dois threads. A ordem de saída pode variar em diferentes máquinas.
// omp_parallel.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
int main() {
#pragma omp parallel num_threads(4)
{
int i = omp_get_thread_num();
printf_s("Hello from thread %d\n", i);
}
}
Hello from thread 0
Hello from thread 1
Hello from thread 2
Hello from thread 3
sections
Identifica as seções de código a serem divididas entre todos os threads.
#pragma omp [parallel] sections [clauses]
{
#pragma omp section
{
code_block
}
}
Parameters
clauses
(Opcional) Zero ou mais cláusulas, consulte a secção Observações .
Remarks
A sections diretiva pode conter zero ou mais section diretivas.
A sections diretiva apoia as seguintes cláusulas:
Se parallel também for especificado, clauses pode ser qualquer cláusula aceita pelas parallelsections ou diretivas, exceto nowait.
Para obter mais informações, consulte 2.4.2 sections construct.
Example
// omp_sections.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
int main() {
#pragma omp parallel sections num_threads(4)
{
printf_s("Hello from thread %d\n", omp_get_thread_num());
#pragma omp section
printf_s("Hello from thread %d\n", omp_get_thread_num());
}
}
Hello from thread 0
Hello from thread 0
single
Permite especificar que uma seção de código deve ser executada em um único thread, não necessariamente no thread principal.
#pragma omp single [clauses]
{
code_block
}
Parameters
clauses
(Opcional) Zero ou mais cláusulas, consulte a secção Observações .
Remarks
A single diretiva apoia as seguintes cláusulas:
Para obter mais informações, consulte 2.4.3 construção única.
Para especificar que uma seção de código só deve ser executada no thread principal, use a diretiva master em vez disso.
Example
// omp_single.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
int main() {
#pragma omp parallel num_threads(2)
{
#pragma omp single
// Only a single thread can read the input.
printf_s("read input\n");
// Multiple threads in the team compute the results.
printf_s("compute results\n");
#pragma omp single
// Only a single thread can write the output.
printf_s("write output\n");
}
}
read input
compute results
compute results
write output
threadprivate
Especifica que uma variável é privada para um thread.
#pragma omp threadprivate(var)
Parameters
var
Uma lista separada por vírgulas de variáveis que você deseja tornar privadas para um thread.
var deve ser uma variável com escopo global ou de namespace ou uma variável estática local.
Remarks
A threadprivate diretiva não suporta cláusulas.
A threadprivate diretiva é baseada no atributo thread usando a palavra-chave threadprivate__declspec(thread) __declspec Por exemplo, uma threadprivate variável existirá em qualquer thread iniciado no processo, não apenas naqueles threads que fazem parte de uma equipe de thread gerada por uma região paralela. Esteja atento a este detalhe de implementação; Você pode notar que os construtores para um threadprivate tipo definido pelo usuário são chamados com mais frequência do que o esperado.
Você pode usar threadprivate em uma DLL que é carregada estaticamente na inicialização do processo, no entanto, você não pode usar threadprivate em qualquer DLL que será carregada via LoadLibrary , como DLLs que são carregadas com /DELAYLOAD (importação de carga de atraso), que também usa LoadLibrary.
Não é garantido que uma threadprivate variável de um tipo destrutível tenha seu destruidor chamado. For example:
struct MyType
{
~MyType();
};
MyType threaded_var;
#pragma omp threadprivate(threaded_var)
int main()
{
#pragma omp parallel
{}
}
Os usuários não têm controle sobre quando os threads que constituem a região paralela serão encerrados. Se esses threads existirem quando o processo for encerrado, os threads não serão notificados sobre a saída do processo e o destruidor não será chamado para threaded_var nenhum thread, exceto aquele que sair (aqui, o thread primário). Portanto, o código não deve contar com a destruição adequada de threadprivate variáveis.
Para obter mais informações, consulte 2.7.1 threadprivate directive.
Example
Para obter um exemplo de uso threadprivatedo , consulte private.