/openmp (OpenMP-Unterstützung aktivieren)

Bewirkt, dass der Compiler #pragma omp Anweisungen zur Unterstützung von OpenMP verarbeitet.

Syntax

/openmp
/openmp:experimental
/openmp:llvm

/openmp

Bemerkungen

#pragma omp wird verwendet, um Direktiven und Klauselnanzugeben. Wenn /openmp in einer Kompilierung nicht angegeben ist, ignoriert der Compiler OpenMP-Klauseln und -Anweisungen. OpenMP-Funktionsaufrufe werden vom Compiler verarbeitet, auch wenn /openmp nicht angegeben ist.

Der C++-Compiler unterstützt derzeit den OpenMP 2.0-Standard. Allerdings bietet Visual Studio 2019 jetzt auch SIMD-Funktionen. Um SIMD zu verwenden, kompilieren Sie mithilfe der /openmp:experimental Option . Diese Option ermöglicht sowohl die üblichen OpenMP-Features als auch OpenMP SIMD-Features, die bei Verwendung des Schalters nicht verfügbar /openmp sind.

Ab Visual Studio 2019 Version 16.9 können Sie die experimentelle Option anstelle /openmp:llvm der /openmp LLVM OpenMP-Runtime verwenden. Für Produktionscode ist derzeit keine Unterstützung verfügbar, da die erforderlichen Libomp-DLLs nicht weiterverteilbar sind. Die Option unterstützt dieselben OpenMP 2.0-Anweisungen wie /openmp . Außerdem werden alle SIMD-Anweisungen unterstützt, die von der Option unterstützt /openmp:experimental werden. Außerdem werden Indizes für ganze Zahlen ohne Vorzeichen parallel für Schleifen gemäß dem OpenMP 3.0-Standard unterstützt. Weitere Informationen finden Sie unter Verbesserte OpenMP-Unterstützung für C++ in Visual Studio.

Derzeit funktioniert die /openmp:llvm Option nur in der x64-Architektur. Die Option ist nicht kompatibel mit /clr oder /ZW .

Anwendungen, die mit und kompiliert /openmp /clr wurden, können nur in einem einzigen Anwendungsdomänenprozess ausgeführt werden. Mehrere Anwendungsdomänen werden nicht unterstützt. Das heißt, wenn der Modulkonstruktor ( ) ausgeführt wird, erkennt er, ob der Prozess mit kompiliert wird, und ob die App in eine nicht standardmäßige Runtime .cctor /openmp geladen wird. Weitere Informationen finden Sie unter appdomain , /clr (Common Language Runtime-Kompilierung)und Initialisierung gemischter Assemblys.

Wenn Sie versuchen, eine App, die sowohl mit als auch kompiliert wurde, in eine nicht standardmäßige Anwendungsdomäne zu laden, wird eine Ausnahme außerhalb des Debuggers ausgelöst, und im Debugger wird eine /openmp /clr Ausnahme TypeInitializationException OpenMPWithMultipleAppdomainsException ausgelöst.

Diese Ausnahmen können auch in den folgenden Situationen ausgelöst werden:

  • Wenn Ihre Anwendung mit kompiliert wird, aber nicht , und in eine nicht standardmäßige Anwendungsdomäne geladen wird, in der der Prozess eine mit kompilierte /clr /openmp App /openmp enthält.

  • Wenn Sie Ihre App an ein Hilfsprogramm übergeben, z. B.regasm.exe, das seine Zielassemblys in eine nicht /clr standardmäßige Anwendungsdomäne lädt.

Die Codezugriffssicherheit der Common Language Runtime funktioniert in OpenMP-Regionen nicht. Wenn Sie ein CLR-Codezugriffssicherheitsattribut außerhalb einer parallelen Region anwenden, ist es in der parallelen Region nicht wirksam.

Microsoft empfiehlt nicht, Apps zu schreiben, /openmp die teilweise vertrauenswürdige Aufrufer zulassen. Verwenden Sie nicht AllowPartiallyTrustedCallersAttribute oder CLR-Codezugriffssicherheitsattribute.

So legen Sie diese Compileroption in der Visual Studio-Entwicklungsumgebung fest

  1. Öffnen Sie das Dialogfeld Eigenschaftenseiten des Projekts. Weitere Informationen erhalten Sie unter Set C++ compiler and build properties in Visual Studio (Festlegen der Compiler- und Buildeigenschaften (C++) in Visual Studio).

  2. Erweitern Sie die Eigenschaftenseite > Konfigurationseigenschaften C/C++-Sprache. >

  3. Ändern Sie die OpenMP-Unterstützungseigenschaft.

So legen Sie diese Compileroption programmgesteuert fest

Beispiel

Das folgende Beispiel zeigt einige der Auswirkungen des Threadpoolstarts im Vergleich zur Verwendung des Threadpools nach dem Start. Angenommen, der Threadpool benötigt etwa 16 ms für den Start eines x64-Prozessors mit einem einzelnen Kern und dualen Prozessoren. Danach gibt es wenig zusätzliche Kosten für den Threadpool.

Wenn Sie mit kompilieren, wird der zweite Aufruf von test2 nie länger ausgeführt, als wenn Sie mit kompilieren, da kein /openmp /openmp- Threadpool gestartet wird. Bei einer Million Iterationen ist die /openmp Version schneller als die Version für den zweiten Aufruf von /openmp- test2. Bei 25 Iterationen registrieren sowohl - als auch /openmp- /openmp -Versionen weniger als die Granularität der Uhr.

Wenn Ihre Anwendung nur eine Schleife enthält und diese in weniger als 15 ms ausgeführt wird (angepasst an den ungefähren Mehraufwand auf Ihrem Computer), /openmp ist möglicherweise nicht geeignet. Wenn dies höher ist, sollten Sie die Verwendung von in Betracht /openmp ziehen.

// 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);
}

Weitere Informationen

MSVC-Compiler Optionen
MSVC-Compiler Befehlszeilensyntax
OpenMP in MSVC