/openmp (Enable OpenMP Support)

Causes the compiler to process #pragma omp directives in support of OpenMP.

Syntax

/openmp
/openmp:experimental
/openmp:llvm

/openmp

Remarks

#pragma omp is used to specify Directives and Clauses. If /openmp isn't specified in a compilation, the compiler ignores OpenMP clauses and directives. OpenMP Function calls are processed by the compiler even if /openmp isn't specified.

The C++ compiler currently supports the OpenMP 2.0 standard. Visual Studio 2019 also now offers SIMD functionality. To use SIMD, compile using the /openmp:experimental option. This option enables both the usual OpenMP features, and OpenMP SIMD features not available when using the /openmp switch.

Starting in Visual Studio 2019 version 16.9, you can use the experimental /openmp:llvm option instead of /openmp to target the LLVM OpenMP runtime. Support currently isn't available for production code, since the required libomp DLLs aren't redistributable. The option supports the same OpenMP 2.0 directives as /openmp. And, it supports all the SIMD directives supported by the /openmp:experimental option. It also supports unsigned integer indices in parallel for loops according to the OpenMP 3.0 standard. For more information, see Improved OpenMP Support for C++ in Visual Studio.

The /openmp:llvm option supports the x64 architecture. Starting with Visual Studio 2019 version 16.10, it also supports the x86 and ARM64 architectures. This option isn't compatible with /clr or /ZW.

Applications compiled by using both /openmp and /clr can only be run in a single application domain process. Multiple application domains aren't supported. That is, when the module constructor (.cctor) is run, it detects if the process is compiled using /openmp, and if the app is loaded into a non-default runtime. For more information, see appdomain, /clr (Common Language Runtime Compilation), and Initialization of Mixed Assemblies.

If you attempt to load an app compiled using both /openmp and /clr into a non-default application domain, a TypeInitializationException exception is thrown outside the debugger, and a OpenMPWithMultipleAppdomainsException exception is thrown in the debugger.

These exceptions can also be raised in the following situations:

  • If your application is compiled using /clr but not /openmp, and is loaded into a non-default application domain, where the process includes an app compiled using /openmp.

  • If you pass your /clr app to a utility, such as regasm.exe, which loads its target assemblies into a non-default application domain.

The common language runtime's code access security doesn't work in OpenMP regions. If you apply a CLR code access security attribute outside a parallel region, it won't be in effect in the parallel region.

Microsoft doesn't recommend that you write /openmp apps that allow partially trusted callers. Don't use AllowPartiallyTrustedCallersAttribute, or any CLR code access security attributes.

To set this compiler option in the Visual Studio development environment

  1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in Visual Studio.

  2. Expand the Configuration Properties > C/C++ > Language property page.

  3. Modify the OpenMP Support property.

To set this compiler option programmatically

Example

The following sample shows some of the effects of thread pool startup versus using the thread pool after it has started. Assuming an x64, single core, dual processor, the thread pool takes about 16 ms to start up. After that, there's little extra cost for the thread pool.

When you compile using /openmp, the second call to test2 never runs any longer than if you compile using /openmp-, as there's no thread pool startup. At a million iterations, the /openmp version is faster than the /openmp- version for the second call to test2. At 25 iterations, both /openmp- and /openmp versions register less than the clock granularity.

If you have only one loop in your application and it runs in less than 15 ms (adjusted for the approximate overhead on your machine), /openmp may not be appropriate. If it's higher, you may want to consider using /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);
}

See also

MSVC compiler options
MSVC compiler command-line syntax
OpenMP in MSVC