/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 개발 환경에서 이 컴파일러 옵션을 설정하려면
프로젝트의 속성 페이지 대화 상자를 엽니다. 자세한 내용은 Visual Studio에서 C++ 컴파일러 및 빌드 속성 설정을 참조하세요.
구성 속성>C/C++>언어 속성 페이지를 확장합니다.
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);
}