3. 런타임 라이브러리 함수
이 섹션에서는 OpenMP C 및 C++ 런타임 라이브러리 함수에 대해 설명합니다. 헤더 <omp.h> 는 병렬 실행 환경을 제어 및 쿼리하는 데 사용할 수 있는 여러 함수와 데이터에 대한 액세스를 동기화하는 데 사용할 수 있는 잠금 함수의 두 가지 형식을 선언합니다.
이 형식 omp_lock_t
은 잠금을 사용할 수 있거나 스레드가 잠금을 소유하고 있음을 나타낼 수 있는 개체 형식입니다. 이러한 잠금을 단순 잠금이라고 합니다.
이 형식은 잠금을 사용할 수 있거나 잠금을 소유하는 스레드의 ID와 중첩 횟수(아래 설명)를 모두 나타낼 수 있는 개체 형식 omp_nest_lock_t
입니다. 이러한 잠금을 중첩 가능한 잠금이라고 합니다.
라이브러리 함수는 "C" 링크가 있는 외부 함수입니다.
이 챕터의 설명은 다음 항목으로 나뉩니다.
3.1 실행 환경 함수
이 섹션에 설명된 함수는 스레드, 프로세서 및 병렬 환경에 영향을 미치고 모니터링합니다.
- omp_set_num_threads
- omp_get_num_threads
- omp_get_max_threads
- omp_get_thread_num
- omp_get_num_procs
- omp_in_parallel
- omp_set_dynamic
- omp_get_dynamic
- omp_set_nested
- omp_get_nested
3.1.1 omp_set_num_threads 함수
이 함수는 omp_set_num_threads
절을 지정 num_threads
하지 않는 이후 병렬 영역에 사용할 기본 스레드 수를 설정합니다. 형식은 다음과 같습니다.
#include <omp.h>
void omp_set_num_threads(int num_threads);
매개 변수 num_threads 값은 양의 정수여야 합니다. 그 효과는 스레드 수의 동적 조정을 사용할 수 있는지 여부에 따라 달라집니다. 함수와 스레드의 동적 조정 간의 omp_set_num_threads
상호 작용에 대한 포괄적인 규칙 집합은 섹션 2.3을 참조하세요.
이 함수에는 함수가 0을 반환하는 프로그램의 일부에서 호출할 때 위에서 설명한 omp_in_parallel
효과가 있습니다. 함수가 0이 아닌 값을 반환하는 omp_in_parallel
프로그램 부분에서 호출되는 경우 이 함수의 동작은 정의되지 않습니다.
이 호출은 환경 변수보다 OMP_NUM_THREADS
우선합니다. 호출 omp_set_num_threads
하거나 환경 변수를 설정 OMP_NUM_THREADS
하여 설정할 수 있는 스레드 수의 기본값은 절을 지정하여 단일 parallel
지시문에서 명시적으로 재정의 num_threads
할 수 있습니다.
자세한 내용은 omp_set_dynamic 참조하세요.
상호 참조
- omp_set_dynamic 함수
- omp_get_dynamic 함수
- OMP_NUM_THREADS 환경 변수
- num_threads 절
3.1.2 omp_get_num_threads 함수
이 함수는 omp_get_num_threads
호출된 병렬 영역을 실행하는 팀의 현재 스레드 수를 반환합니다. 형식은 다음과 같습니다.
#include <omp.h>
int omp_get_num_threads(void);
절, omp_set_num_threads
함수 및 환경 변수는 num_threads
OMP_NUM_THREADS
팀의 스레드 수를 제어합니다.
사용자가 스레드 수를 명시적으로 설정하지 않은 경우 기본값은 구현 정의입니다. 이 함수는 가장 가까운 바깥쪽 지시문에 바인딩됩니다 parallel
. 프로그램의 직렬 부분이나 serialize된 중첩된 병렬 영역에서 호출되는 경우 이 함수는 1을 반환합니다.
자세한 내용은 omp_set_dynamic 참조하세요.
상호 참조
3.1.3 omp_get_max_threads 함수
이 함수는 omp_get_max_threads
코드의 해당 지점에서 절이 없는 num_threads
병렬 영역을 볼 수 있는 경우 팀을 구성하는 데 사용할 스레드 수만큼 큰 정수를 반환합니다. 형식은 다음과 같습니다.
#include <omp.h>
int omp_get_max_threads(void);
다음은 다음 값 omp_get_max_threads
에 하한을 표시합니다.
threads-used-for-next-team<=
omp_get_max_threads
다른 병렬 지역이 절을 num_threads
사용하여 특정 수의 스레드를 요청하는 경우 결과의 omp_get_max_threads
하한에 대한 보장은 더 이상 유지되지 않습니다.
omp_get_max_threads
함수의 반환 값을 사용하여 다음 병렬 지역에 형성된 팀의 모든 스레드에 대해 충분한 스토리지를 동적으로 할당할 수 있습니다.
상호 참조
3.1.4 omp_get_thread_num 함수
함수는 omp_get_thread_num
해당 팀 내에서 함수를 실행하는 스레드의 스레드 번호를 반환합니다. 스레드 번호는 0에서 -1 사이이며 omp_get_num_threads()
포함됩니다. 팀의 마스터 스레드는 스레드 0입니다.
형식은 다음과 같습니다.
#include <omp.h>
int omp_get_thread_num(void);
직렬 지역에서 호출되는 경우 0을 omp_get_thread_num
반환합니다. serialize된 중첩된 병렬 영역 내에서 호출되는 경우 이 함수는 0을 반환합니다.
상호 참조
3.1.5 omp_get_num_procs 함수
함수는 omp_get_num_procs
함수가 호출되는 시점에 프로그램에서 사용할 수 있는 프로세서 수를 반환합니다. 형식은 다음과 같습니다.
#include <omp.h>
int omp_get_num_procs(void);
3.1.6 omp_in_parallel 함수
함수는 omp_in_parallel
병렬로 실행되는 병렬 영역의 동적 범위 내에서 호출되는 경우 0이 아닌 값을 반환하고, 그렇지 않으면 0을 반환합니다. 형식은 다음과 같습니다.
#include <omp.h>
int omp_in_parallel(void);
이 함수는 직렬화된 중첩된 지역을 포함하여 병렬로 실행되는 지역 내에서 호출될 때 0이 아닌 값을 반환합니다.
3.1.7 omp_set_dynamic 함수
이 함수는 omp_set_dynamic
병렬 영역 실행에 사용할 수 있는 스레드 수를 동적으로 조정하거나 사용하지 않도록 설정합니다. 형식은 다음과 같습니다.
#include <omp.h>
void omp_set_dynamic(int dynamic_threads);
dynamic_threads 0이 아닌 값으로 평가되는 경우 런타임 환경에서 예정된 병렬 영역을 실행하는 데 사용되는 스레드 수를 자동으로 조정하여 시스템 리소스를 가장 잘 사용할 수 있습니다. 결과적으로 사용자가 지정한 스레드 수는 최대 스레드 수입니다. 병렬 지역을 실행하는 팀의 스레드 수는 해당 병렬 영역의 기간 동안 고정된 상태로 유지되며 함수에 omp_get_num_threads
의해 보고됩니다.
dynamic_threads 0으로 평가되면 동적 조정이 비활성화됩니다.
이 함수에는 함수가 0을 반환하는 프로그램의 일부에서 호출할 때 위에서 설명한 omp_in_parallel
효과가 있습니다. 함수가 0이 아닌 값을 반환하는 omp_in_parallel
프로그램 부분에서 호출되는 경우 이 함수의 동작은 정의되지 않습니다.
호출이 omp_set_dynamic
환경 변수보다 우선합니다 OMP_DYNAMIC
.
스레드의 동적 조정에 대한 기본값은 구현 정의입니다. 따라서 올바른 실행을 위해 특정 수의 스레드에 의존하는 사용자 코드는 동적 스레드를 명시적으로 사용하지 않도록 설정해야 합니다. 구현은 스레드 수를 동적으로 조정하는 기능을 제공하는 데 필요하지 않지만 모든 플랫폼에서 이식성을 지원하는 인터페이스를 제공해야 합니다.
Microsoft 전용
현재 지원 omp_get_dynamic
omp_set_dynamic
되는 지원은 다음과 같습니다.
입력 매개 변수 omp_set_dynamic
는 스레딩 정책에 영향을 주지 않으며 스레드 수를 변경하지 않습니다. omp_get_num_threads
는 설정된 경우 항상 사용자 정의 번호 또는 기본 스레드 번호를 반환합니다. 현재 Microsoft 구현 omp_set_dynamic(0)
에서는 다음 병렬 지역에 기존 스레드 집합을 다시 사용할 수 있도록 동적 스레딩을 해제합니다. omp_set_dynamic(1)
는 기존 스레드 집합을 삭제하고 예정된 병렬 지역에 대한 새 집합을 만들어 동적 스레딩을 설정합니다. 새 집합의 스레드 수는 이전 집합과 동일하며 반환 값을 omp_get_num_threads
기반으로 합니다. 따라서 최상의 성능을 위해 기존 스레드를 다시 사용하는 데 사용합니다 omp_set_dynamic(0)
.
상호 참조
3.1.8 omp_get_dynamic 함수
스레드의 동적 조정이 활성화된 경우 함수는 omp_get_dynamic
0이 아닌 값을 반환하고, 그렇지 않으면 0을 반환합니다. 형식은 다음과 같습니다.
#include <omp.h>
int omp_get_dynamic(void);
구현에서 스레드 수의 동적 조정을 구현하지 않는 경우 이 함수는 항상 0을 반환합니다. 자세한 내용은 omp_set_dynamic 참조하세요.
상호 참조
- 동적 스레드 조정에 대한 설명은 omp_set_dynamic 참조하세요.
3.1.9 omp_set_nested 함수
이 함수는 omp_set_nested
중첩된 병렬 처리를 사용하거나 사용하지 않도록 설정합니다. 형식은 다음과 같습니다.
#include <omp.h>
void omp_set_nested(int nested);
중첩된 병렬 처리가 0으로 계산되면 기본값인 중첩된 병렬 처리가 비활성화되고 중첩된 병렬 영역이 현재 스레드에 의해 직렬화되고 실행됩니다. 그렇지 않으면 중첩된 병렬 처리가 사용되며 중첩된 병렬 영역은 추가 스레드를 배포하여 중첩 팀 형성할 수 있습니다.
이 함수에는 함수가 0을 반환하는 프로그램의 일부에서 호출할 때 위에서 설명한 omp_in_parallel
효과가 있습니다. 함수가 0이 아닌 값을 반환하는 omp_in_parallel
프로그램 부분에서 호출되는 경우 이 함수의 동작은 정의되지 않습니다.
이 호출은 환경 변수보다 OMP_NESTED
우선합니다.
중첩 병렬 처리를 사용하도록 설정하면 중첩된 병렬 영역을 실행하는 데 사용되는 스레드 수가 구현에서 정의됩니다. 따라서 중첩된 병렬 처리를 사용하는 경우에도 OpenMP 규격 구현에서 중첩된 병렬 영역을 직렬화할 수 있습니다.
상호 참조
3.1.10 omp_get_nested 함수
함수는 omp_get_nested
중첩된 병렬 처리가 사용되는 경우 0이 아닌 값을 반환하고, 사용하지 않도록 설정된 경우 0을 반환합니다. 중첩 병렬 처리에 대한 자세한 내용은 omp_set_nested 참조하세요. 형식은 다음과 같습니다.
#include <omp.h>
int omp_get_nested(void);
구현에서 중첩된 병렬 처리를 구현하지 않는 경우 이 함수는 항상 0을 반환합니다.
3.2 잠금 함수
이 섹션에 설명된 함수는 동기화에 사용되는 잠금을 조작합니다.
다음 함수의 경우 잠금 변수에 형식 omp_lock_t
이 있어야 합니다. 이 변수는 이러한 함수를 통해서만 액세스해야 합니다. 모든 잠금 함수에는 형식에 대한 포인터 omp_lock_t
가 있는 인수가 필요합니다.
- omp_init_lock 함수는 간단한 잠금을 초기화합니다.
- omp_destroy_lock 함수는 간단한 잠금을 제거합니다.
- omp_set_lock 함수는 간단한 잠금을 사용할 수 있게 될 때까지 기다립니다.
- omp_unset_lock 함수는 간단한 잠금을 해제합니다.
- omp_test_lock 함수는 간단한 잠금을 테스트합니다.
다음 함수의 경우 잠금 변수에 형식 omp_nest_lock_t
이 있어야 합니다. 이 변수는 이러한 함수를 통해서만 액세스해야 합니다. 모든 중첩 가능한 잠금 함수에는 형식에 대한 포인터 omp_nest_lock_t
가 있는 인수가 필요합니다.
- omp_init_nest_lock 함수는 중첩 가능한 잠금을 초기화합니다.
- omp_destroy_nest_lock 함수는 중첩 가능한 잠금을 제거합니다.
- omp_set_nest_lock 함수는 중첩 가능한 잠금을 사용할 수 있게 될 때까지 기다립니다.
- omp_unset_nest_lock 함수는 중첩 가능한 잠금을 해제합니다.
- omp_test_nest_lock 함수는 중첩 가능한 잠금을 테스트합니다.
OpenMP 잠금 함수는 잠금 변수의 최신 값을 항상 읽고 업데이트하는 방식으로 잠금 변수에 액세스합니다. 따라서 OpenMP 프로그램에서 명시적 flush
지시문을 포함하여 잠금 변수의 값이 서로 다른 스레드 간에 일관되도록 할 필요는 없습니다. (지시문이 다른 변수의 값을 일관되게 만들 필요가 flush
있을 수 있습니다.)
3.2.1 omp_init_lock 및 omp_init_nest_lock 함수
이러한 함수는 잠금을 초기화하는 유일한 방법을 제공합니다. 각 함수는 예정된 호출에서 사용할 매개 변수 잠금과 연결된 잠금 을 초기화합니다. 형식은 다음과 같습니다.
#include <omp.h>
void omp_init_lock(omp_lock_t *lock);
void omp_init_nest_lock(omp_nest_lock_t *lock);
초기 상태가 잠금 해제됩니다(즉, 잠금을 소유하는 스레드가 없음). 중첩 가능한 잠금의 경우 초기 중첩 수는 0입니다. 이미 초기화된 잠금 변수를 사용하여 이러한 루틴 중 하나를 호출하는 것은 비준수입니다.
3.2.2 omp_destroy_lock 및 omp_destroy_nest_lock 함수
이러한 함수는 뾰족한 잠금 변수 잠금 이 초기화되지 않았는지 확인합니다. 형식은 다음과 같습니다.
#include <omp.h>
void omp_destroy_lock(omp_lock_t *lock);
void omp_destroy_nest_lock(omp_nest_lock_t *lock);
초기화되지 않았거나 잠금 해제된 잠금 변수를 사용하여 이러한 루틴 중 하나를 호출하는 것은 비준수입니다.
3.2.3 omp_set_lock 및 omp_set_nest_lock 함수
이러한 각 함수는 지정된 잠금을 사용할 수 있게 될 때까지 함수를 실행하는 스레드를 차단한 다음 잠금을 설정합니다. 잠금 해제된 경우 간단한 잠금을 사용할 수 있습니다. 잠금이 해제되었거나 함수를 실행하는 스레드가 이미 소유하고 있는 경우 중첩 가능한 잠금을 사용할 수 있습니다. 형식은 다음과 같습니다.
#include <omp.h>
void omp_set_lock(omp_lock_t *lock);
void omp_set_nest_lock(omp_nest_lock_t *lock);
단순 잠금의 경우 함수에 대한 인수는 omp_set_lock
초기화된 잠금 변수를 가리킵니다. 잠금의 소유권은 함수를 실행하는 스레드에 부여됩니다.
중첩 가능한 잠금의 경우 함수에 대한 인수는 omp_set_nest_lock
초기화된 잠금 변수를 가리킵니다. 중첩 횟수가 증가하며 스레드에 잠금 소유권이 부여되거나 유지됩니다.
3.2.4 omp_unset_lock 및 omp_unset_nest_lock 함수
이러한 함수는 잠금의 소유권을 해제하는 수단을 제공합니다. 형식은 다음과 같습니다.
#include <omp.h>
void omp_unset_lock(omp_lock_t *lock);
void omp_unset_nest_lock(omp_nest_lock_t *lock);
이러한 각 함수에 대한 인수는 함수를 실행하는 스레드가 소유한 초기화된 잠금 변수를 가리킵니다. 스레드가 해당 잠금을 소유하지 않는 경우 동작이 정의되지 않습니다.
간단한 잠금의 경우 함수는 omp_unset_lock
잠금의 소유권에서 함수를 실행하는 스레드를 해제합니다.
중첩 가능한 잠금의 경우 함수는 omp_unset_nest_lock
중첩 횟수를 감소시키고 결과 수가 0인 경우 함수를 실행하는 스레드를 잠금 소유권에서 해제합니다.
3.2.5 omp_test_lock 및 omp_test_nest_lock 함수
이러한 함수는 잠금을 설정하려고 하지만 스레드 실행을 차단하지는 않습니다. 형식은 다음과 같습니다.
#include <omp.h>
int omp_test_lock(omp_lock_t *lock);
int omp_test_nest_lock(omp_nest_lock_t *lock);
인수는 초기화된 잠금 변수를 가리킵니다. 이러한 함수는 스레드 실행을 차단하지 않는다는 점을 제외하고 잠금을 동일한 방식으로 omp_set_lock
omp_set_nest_lock
설정하려고 합니다.
단순 잠금의 경우 잠금이 omp_test_lock
성공적으로 설정되면 함수는 0이 아닌 값을 반환하고, 그렇지 않으면 0을 반환합니다.
중첩 가능한 잠금의 omp_test_nest_lock
경우 잠금이 성공적으로 설정되면 함수는 새 중첩 횟수를 반환하고, 그렇지 않으면 0을 반환합니다.
3.3 타이밍 루틴
이 섹션에 설명된 함수는 이식 가능한 벽시계 타이머를 지원합니다.
3.3.1 omp_get_wtime 함수
이 함수는 omp_get_wtime
"과거의 시간" 이후 경과된 벽 클록 시간과 동일한 배정밀도 부동 소수점 값을 초 단위로 반환합니다. 실제 "과거의 시간"은 임의적이지만 애플리케이션 프로그램을 실행하는 동안 변경되지 않도록 보장됩니다. 형식은 다음과 같습니다.
#include <omp.h>
double omp_get_wtime(void);
다음 예제와 같이 함수를 사용하여 경과 시간을 측정할 것으로 예상됩니다.
double start;
double end;
start = omp_get_wtime();
... work to be timed ...
end = omp_get_wtime();
printf_s("Work took %f sec. time.\n", end-start);
반환되는 시간은 "스레드당 시간"이며, 이는 애플리케이션에 참여하는 모든 스레드에서 전역적으로 일관성을 유지하지 않아도 됨을 의미합니다.
3.3.2 omp_get_wtick 함수
이 함수는 omp_get_wtick
연속 클록 틱 사이의 초 수와 동일한 배정밀도 부동 소수점 값을 반환합니다. 형식은 다음과 같습니다.
#include <omp.h>
double omp_get_wtick(void);