/openmp (OpenMP-Unterstützung aktivieren)

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

Syntax

/openmp
/openmp:experimental
/openmp:llvm

/openmp

Hinweise

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

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

Ab Visual Studio 2019, Version 16.9, können Sie die experimentelle /openmp:llvm Option anstelle der /openmp LLVM OpenMP-Laufzeit verwenden. Die Unterstützung ist derzeit für Produktionscode nicht verfügbar, da die erforderlichen libomp-DLLs nicht weiterverteilt werden können. Die Option unterstützt die gleichen OpenMP 2.0-Direktiven wie /openmp. Außerdem werden alle SIMD-Direktiven unterstützt, die von der /openmp:experimental Option unterstützt werden. Es unterstützt auch nicht signierte ganzzahlige Indizes parallel für Schleifen gemäß dem OpenMP 3.0-Standard. Weitere Informationen finden Sie unter Verbesserte OpenMP-Unterstützung für C++ in Visual Studio.

Die /openmp:llvm Option unterstützt die x64-Architektur. Ab Visual Studio 2019, Version 16.10, unterstützt sie auch die x86- und ARM64-Architekturen. Diese Option ist nicht kompatibel mit /clr oder /ZW.

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

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

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

  • Wenn Ihre Anwendung mit /clr , aber nicht /openmpkompiliert wird und in eine nicht standardmäßige Anwendungsdomäne geladen wird, in der der Prozess eine app kompiliert /openmpmit einschließt.

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

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

Microsoft empfiehlt nicht, Apps zu schreiben /openmp , die teilweise vertrauenswürdige Anrufer zulassen. Verwenden AllowPartiallyTrustedCallersAttributeSie weder CLR-Codezugriffssicherheitsattribute noch CLR-Code.

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 Konfigurationseigenschaftenseite>C/C++Language.>

  3. Ändern Sie die OpenMP-Supporteigenschaft .

So legen Sie diese Compileroption programmgesteuert fest

Beispiel

Das folgende Beispiel zeigt einige der Auswirkungen des Threadpoolstarts im Vergleich zur Verwendung des Threadpools, nachdem er gestartet wurde. Bei einem x64-, Single-Core-, Dual-Prozessor dauert der Threadpool etwa 16 ms zum Starten. Danach gibt es wenig zusätzliche Kosten für den Threadpool.

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

Wenn Sie nur eine Schleife in Ihrer Anwendung haben und sie in weniger als 15 ms ausgeführt wird (angepasst auf den ungefähren Aufwand auf Ihrem Computer), /openmp ist möglicherweise nicht geeignet. Wenn dies höher ist, sollten Sie die Verwendung /openmpin Betracht 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);
}

Siehe auch

MSVC-Compileroptionen
Syntax für die MSVC-Compilerbefehlszeile
OpenMP in MSVC