/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하세요.

기본이 아닌 애플리케이션 도메인 TypeInitializationException 을 사용하여 /openmp /clr 컴파일된 앱을 로드하려고 하면 디버거 외부에서 예외가 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