/openmp (OpenMP 지원 사용)

컴파일러가 OpenMP를 지원하는 지시문을 처리 #pragma omp 하도록 합니다.

구문

/openmp
/openmp:experimental
/openmp:llvm

/openmp

설명

#pragma omp는 지시문 및 절을 지정하는 데 사용됩니다. 컴파일에 지정되지 않은 경우 /openmp 컴파일러는 OpenMP 절 및 지시문을 무시합니다. OpenMP 함수 호출은 지정되지 않은 경우에도 /openmp 컴파일러에서 처리됩니다.

C++ 컴파일러는 현재 OpenMP 2.0 표준을 지원합니다. Visual Studio 2019는 이제 SIMD 기능도 제공합니다. SIMD를 사용하려면 이 옵션을 사용하여 컴파일합니다 /openmp:experimental . 이 옵션을 사용하면 일반적인 OpenMP 기능과 스위치를 사용할 /openmp 때는 OpenMP SIMD 기능을 모두 사용할 수 없습니다.

Visual Studio 2019 버전 16.9부터 LLVM OpenMP 런타임을 대상으로 하는 대신 /openmp 실험적 /openmp:llvm 옵션을 사용할 수 있습니다. 필요한 libomp DLL은 재배포할 수 없으므로 현재 프로덕션 코드에는 지원을 사용할 수 없습니다. 이 옵션은 .와 동일한 OpenMP 2.0 지시문을 지원합니다 /openmp. 또한 옵션에서 지원하는 모든 SIMD 지시문을 지원 /openmp:experimental 합니다. 또한 OpenMP 3.0 표준에 따라 루프에 대해 부호 없는 정수 인덱스를 병렬로 지원합니다. 자세한 내용은 Visual Studio에서 C++에 대한 향상된 OpenMP 지원을 참조 하세요.

/openmp:llvm 옵션은 x64 아키텍처를 지원합니다. Visual Studio 2019 버전 16.10부터 x86 및 ARM64 아키텍처도 지원합니다. 이 옵션은 호환 /clr 되지 않습니다./ZW

둘 다 /openmp/clr 사용하여 컴파일되고 단일 애플리케이션에서만 실행할 수 있는 애플리케이션은 기본 프로세스입니다. 여러 애플리케이션이 기본 지원되지 않습니다. 즉, 모듈 생성자(.cctor)가 실행될 때 프로세스를 사용하여 /openmp컴파일되는지, 그리고 앱이 기본이 아닌 런타임으로 로드되는지를 검색합니다. 자세한 내용은 혼합 어셈블리의 , /clr (공용 언어 런타임 컴파일)초기화를 참조appdomain하세요.

둘 다 /openmp/clr 사용하여 컴파일된 앱을 기본이 아닌 애플리케이션으로 로드하려고 하면기본 TypeInitializationException 예외가 디버거 외부에서 throw되고 OpenMPWithMultipleAppdomainsException 디버거에서 예외가 throw됩니다.

이러한 예외는 다음과 같은 상황에서도 발생할 수 있습니다.

  • 애플리케이션을 사용 /clr 하되 사용하지 않고 컴파일하고 기본이 아닌 /openmp애플리케이션으로 로드하는 경우기본 프로세스에 사용하여 /openmp컴파일된 앱이 포함됩니다.

  • 대상 어셈블리를 기본이 아닌 애플리케이션으로 로드하는 regasm.exe와 같은 유틸리티에 앱을 /clr 전달하는 경우 기본.

공용 언어 런타임의 코드 액세스 보안은 OpenMP 지역에서 작동하지 않습니다. 병렬 지역 외부에 CLR 코드 액세스 보안 특성을 적용하는 경우 병렬 지역에 적용되지 않습니다.

Microsoft는 부분적으로 신뢰할 수 있는 호출자를 허용하는 앱을 작성하는 /openmp 것이 좋습니다. 또는 CLR 코드 액세스 보안 특성을 사용하지 AllowPartiallyTrustedCallersAttribute마세요.

Visual Studio 개발 환경에서 이 컴파일러 옵션을 설정하려면

  1. 프로젝트의 속성 페이지 대화 상자를 엽니다. 자세한 내용은 Visual Studio에서 C++ 컴파일러 및 빌드 속성 설정을 참조하세요.

  2. 구성 속성>C/C++>언어 속성 페이지를 확장합니다.

  3. OpenMP 지원 속성을 수정합니다.

프로그래밍 방식으로 이 컴파일러 옵션을 설정하려면

  • OpenMP을(를) 참조하세요.

예시

다음 샘플에서는 스레드 풀이 시작된 후 스레드 풀을 사용하는 것과 스레드 풀 시작의 영향 중 일부를 보여 줍니다. x64, 단일 코어, 이중 프로세서를 가정하면 스레드 풀을 시작하는 데 약 16ms가 걸립니다. 그 후에는 스레드 풀에 대한 추가 비용이 거의 없습니다.

사용하여 /openmp컴파일하는 경우 스레드 풀 시작이 없으므로 test2에 대한 두 번째 호출은 컴파일 /openmp-하는 경우보다 더 이상 실행되지 않습니다. 백만 번의 반복에서 /openmp 버전은 test2에 대한 두 번째 호출 버전보다 /openmp- 빠릅니다. 25회 반복 시 두 버전 모두 /openmp-/openmp 클록 세분성보다 적게 등록됩니다.

애플리케이션에 루프가 하나만 있고 15ms 미만으로 실행되는 경우(컴퓨터의 대략적인 오버헤드에 맞게 조정됨) /openmp 적절하지 않을 수 있습니다. 이 값이 더 높은 /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);
}

참고 항목

MSVC 컴파일러 옵션
MSVC 컴파일러 명령줄 구문
MSVC의 OpenMP