Compartilhar via


/openmp (habilitar suporte a OpenMP)

Faz com que o compilador processe diretivas #pragma omp em suporte ao OpenMP.

Sintaxe

/openmp
/openmp:experimental
/openmp:llvm

/openmp

Comentários

#pragma omp é usado para especificar Diretivas e Cláusulas. Se /openmp não for especificado em uma compilação, o compilador ignorará as cláusulas e diretivas OpenMP. As chamadas da função OpenMP são processadas pelo compilador mesmo que /openmp não seja especificada.

O compilador C++ atualmente dá suporte ao padrão OpenMP 2.0. O Visual Studio 2019 agora também oferece a funcionalidade SIMD. Para usar o SIMD, compile usando a /openmp:experimental opção. Essa opção habilita os recursos comuns do OpenMP e os recursos do OpenMP SIMD não disponíveis ao usar a opção /openmp.

A partir do Visual Studio 2019 versão 16.9, você pode usar a opção experimental /openmp:llvm em vez de /openmp direcionar o runtime do OpenMP da LLVM. Atualmente, o suporte não está disponível para código de produção, pois as DLLs de libomp necessárias não são redistribuíveis. A opção dá suporte às mesmas diretivas OpenMP 2.0 que /openmp. Além disso, ela dá suporte a todas as diretivas SIMD compatíveis com a opção /openmp:experimental. Ele também dá suporte a índices inteiros sem sinal em paralelo para loops de acordo com o padrão OpenMP 3.0. Para obter mais informações, consulte Suporte do OpenMP aprimorado para C++ no Visual Studio.

A /openmp:llvm opção dá suporte à arquitetura x64. A partir do Visual Studio 2019 versão 16.10, ele também dá suporte às arquiteturas x86 e ARM64. Essa opção não é compatível com /clr ou /ZW.

Os aplicativos compilados usando ambos /openmp e /clr só podem ser executados em um único processo de domínio do aplicativo. Não há suporte para vários domínios de aplicativo. Ou seja, quando o construtor do módulo (.cctor) é executado, ele detecta se o processo é compilado usando /openmp e, se o aplicativo é carregado em um runtime não padrão. Para obter mais informações, consulte appdomain, /clr (Compilação common language runtime) e Inicialização de assemblies mistos.

Se você tentar carregar um aplicativo compilado usando ambos /openmp e /clr em um domínio de aplicativo não padrão, uma exceção TypeInitializationException será lançada fora do depurador e uma exceção OpenMPWithMultipleAppdomainsException será lançada no depurador.

Essas exceções também podem ser geradas nas seguintes situações:

  • Se o aplicativo for compilado usando /clr, mas não /openmp, e for carregado em um domínio de aplicativo não padrão, onde o processo incluirá um aplicativo compilado usando /openmp.

  • Se você passar seu aplicativo /clr para um utilitário, como regasm.exe, que carrega seus assemblies de destino em um domínio de aplicativo não padrão.

A segurança de acesso ao código do Common Language Runtime não funciona em regiões OpenMP. Se você aplicar um atributo de segurança de acesso de código CLR fora de uma região paralela, ele não estará em vigor na região paralela.

A Microsoft não recomenda que você escreva aplicativos /openmp que permitem chamadores parcialmente confiáveis. Não use AllowPartiallyTrustedCallersAttribute, ou nenhum atributo de segurança de acesso de código CLR.

Para definir esta opção do compilador no ambiente de desenvolvimento do Visual Studio

  1. Abra a caixa de diálogo Páginas de Propriedades do projeto. Para obter detalhes, confira Definir as propriedades de build e do compilador do C++ no Visual Studio.

  2. Expanda a página de propriedades Propriedades da Configuração>C/C++>Linguagem.

  3. Modifique a propriedade de Suporte do OpenMP.

Para definir essa opção do compilador via programação

Exemplo

A amostra a seguir mostra alguns dos efeitos da inicialização do pool de threads em vez de usar o pool de threads depois que ele for iniciado. Supondo que um processador x64, núcleo único, duplo, o pool de threads leve cerca de 16 ms para iniciar. Depois disso, há pouco custo extra para o pool de threads.

Quando você compila usando /openmp, a segunda chamada para test2 nunca é executada por mais tempo do que se você compilar usando /openmp-, pois não há nenhuma inicialização do pool de threads. Em um milhão de iterações, a versão /openmp é mais rápida que a versão /openmp- para a segunda chamada para test2. Em 25 iterações, ambas a versões, /openmp- e /openmp, registram menos que a granularidade do relógio.

Se você tiver apenas um loop em seu aplicativo e ele for executado em menos de 15 ms (ajustado para a sobrecarga aproximada em seu computador), /openmp talvez não seja apropriado. Se for maior, talvez você queira considerar o uso de /openmp.

// cpp_compiler_options_openmp.cpp
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

volatile DWORD dwStart;
volatile int global = 0;

double test2(int num_steps) {
   int i;
   global++;
   double x, pi, sum = 0.0, step;

   step = 1.0 / (double) num_steps;

   #pragma omp parallel for reduction(+:sum) private(x)
   for (i = 1; i <= num_steps; i++) {
      x = (i - 0.5) * step;
      sum = sum + 4.0 / (1.0 + x*x);
   }

   pi = step * sum;
   return pi;
}

int main(int argc, char* argv[]) {
   double   d;
   int n = 1000000;

   if (argc > 1)
      n = atoi(argv[1]);

   dwStart = GetTickCount();
   d = test2(n);
   printf_s("For %d steps, pi = %.15f, %d milliseconds\n", n, d, GetTickCount() - dwStart);

   dwStart = GetTickCount();
   d = test2(n);
   printf_s("For %d steps, pi = %.15f, %d milliseconds\n", n, d, GetTickCount() - dwStart);
}

Confira também

Opções do compilador MSVC
Sintaxe da linha de comando do compilador MSVC
OpenMP no MSVC