/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
Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in Visual Studio.
Expand the Configuration Properties > C/C++ > Language property page.
Modify the OpenMP Support property.
To set this compiler option programmatically
- See OpenMP.
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