OpenACC
1. 개요
OpenACC는 가속기를 활용한 병렬 프로그래밍을 위한 지시어 기반의 표준이다. PGI와 Cray, OpenUH, OpenARC, 옴니 컴파일러, IPMACC 등 다양한 컴파일러에서 OpenACC를 지원하며, GCC에서도 OpenACC 지원이 이루어졌다. OpenACC는 지시어와 런타임 라이브러리를 통해 사용되며, 주요 지시어로는 `#pragma acc parallel`, `#pragma acc kernels`, `#pragma acc data` 등이 있다. 런타임 API 함수는 장치 관리, 비동기 작업 제어, 메모리 관리 등을 제공한다.
| 이름 | OpenACC |
|---|---|
| 종류 | API (응용 프로그래밍 인터페이스) |
| 개발자 | OpenACC 조직 |
| 플랫폼 | 크로스 플랫폼 |
| 장르 | API (응용 프로그래밍 인터페이스) |
| 최신 버전 | 3.3 |
| 최신 릴리스 날짜 | 2022년 11월 |
| 프로그래밍 언어 | C C++ Fortran |
| 운영 체제 | 크로스 플랫폼 |
| 웹사이트 | OpenACC 공식 웹사이트 |
-
포트란 -
존 배커스
존 배커스는 FORTRAN 프로그래밍 언어 설계 및 개발, ALGOL 60 개발 참여 및 바커스-나우르 표기법 고안 등 컴퓨터 과학에 기여한 미국의 과학자이다. -
포트란 -
OpenMP
OpenMP는 공유 메모리 병렬 시스템에서 병렬 프로그래밍을 지원하는 API로, 컴파일러 지시문, 라이브러리 루틴, 환경 변수 등을 통해 병렬 영역 설정, 작업 분담, 데이터 관리, 스레드 동기화 등을 수행하며, 점진적인 병렬화가 가능하고 이식성이 높다. -
C 프로그래밍 언어 계열 -
C (프로그래밍 언어)
C는 하드웨어 제어와 이식성이 뛰어난 고급 절차적 프로그래밍 언어로서, 다양한 분야에서 사용되며 후속 언어에 영향을 주었고, 성능과 효율성이 높지만 안전성 문제 개선이 필요한 언어이다. -
C 프로그래밍 언어 계열 -
펄
펄은 래리 월이 개발한 텍스트 조작에 강점을 가진 다목적 프로그래밍 언어이며, 1987년 펄 1.0이 처음 공개된 이후 여러 버전 업데이트를 거쳐 객체 지향 프로그래밍과 유니코드 지원 기능을 추가했고, 현재 펄 5가 널리 사용되며 CPAN을 통해 방대한 모듈 생태계를 제공한다. -
표준 -
국제단위계
국제단위계(SI)는 7개의 기본 상수 값을 고정하여 정의되는 국제적인 측정 단위 체계로, 2019년 재정의를 통해 자연 상수에 기반하여 측정의 정확도와 재현성을 향상시켰다. -
표준 -
QR 코드
QR 코드는 1994년 일본 덴소 웨이브가 개발한 2차원 바코드로, 기존 바코드보다 많은 정보를 저장하고 오류 정정 기능이 있으며, 자동차 부품 관리에서 시작하여 다양한 분야에서 활용되지만 악성 QR 코드에 의한 피해에도 주의해야 한다.
2. 컴파일러 지원
OpenACC는 다양한 상용 및 오픈 소스 컴파일러에서 지원된다. PGI와 크레이는 상용 컴파일러에서, OpenUH, OpenARC, 옴니 컴파일러, IPMACC, GCC는 오픈 소스 컴파일러에서 OpenACC를 지원한다. 각 컴파일러에 대한 자세한 내용은 하위 섹션을 참고할 수 있다.
2.2. 오픈 소스 컴파일러
OpenUH는 오픈64 기반의 오픈 소스 OpenACC 컴파일러로, 휴스턴 대학교 HPCTools 그룹에서 개발했으며 C와 FORTRAN을 지원한다.
OpenARC는 오크리지 국립 연구소에서 개발한 오픈 소스 C 컴파일러로, OpenACC 1.0 사양의 모든 기능을 지원한다. 라 라구나 대학교에서 개발된 accULL은 실험적인 오픈 소스 C 컴파일러이다.
옴니 컴파일러(Omni Compiler)는 쓰쿠바 대학 HPCS 연구소와 RIKEN (이화학연구소) 계산 과학 연구 센터 프로그래밍 환경 연구팀에서 개발한 오픈 소스 컴파일러로, XcalableMP, OpenACC, XcalableACC일본어를 지원한다.
IPMACC는 빅토리아 대학교에서 개발한 오픈 소스 C 컴파일러로, OpenACC를 CUDA, OpenCL 및 ISPC로 변환한다. 현재 data, kernels, loop, cache 지시어만 지원한다.
GCC의 OpenACC 지원은 늦게 이루어졌다. 삼성은 GPU를 대상으로 OpenACC 1.1 코드를 OpenCL로 변환하는 구현을 2013년 9월에 발표했다. NVIDIA는 OpenACC 2.0 기반으로 PTX 어셈블리 언어를 타겟으로 하는 구현을 발표했다. GCC 5.1 버전부터 OpenACC/PTX에 대한 실험적인 지원이 추가되었고, GCC 9.1에서는 OpenACC 2.5 지원이 거의 완성되었다.
3. 사용 방법
OpenACC의 주요 프로그래밍 방식은 OpenMP 3.x 버전이나 초기 OpenHMPP와 유사하게 지시어이다. C 언어에서는 "openacc.h", Fortran에서는 "openacc_lib.h"를 포함시킨 후 acc_init() 함수를 호출하여 런타임 라이브러리를 초기화하고 사용할 수 있다.
3.1. 지시어 (Directives)
OpenACC는 광범위한 프라그마(지시어) 목록을 정의한다.
```c
#pragma acc parallel
#pragma acc kernels
```
위 두 지시어는 가속기에서 실행될 병렬 계산 커널(여기서 커널은 운영체제의 핵심 부분이 아닌, 가속기에서 실행되는 계산 프로그램을 의미한다)을 정의하는 데 사용되며, 서로 다른 의미를 갖는다.
```c
#pragma acc data
```
위 지시어는 데이터를 가속기로 복사하거나 가속기에서 데이터를 복사하는 것을 정의하는 주요 지시어이다.
```c
#pragma acc loop
```
위 지시어는 `parallel` 또는 `kernels` 영역에서 병렬 처리 유형을 정의하는 데 사용된다.
```c
#pragma acc cache
#pragma acc update
#pragma acc declare
#pragma acc wait
3.2. 런타임 API
OpenACC는 장치 관리, 비동기 작업 제어, 메모리 관리 등을 수행하기 위한 런타임 API 함수를 제공한다. 주요 함수는 다음과 같다.
* `acc_get_num_devices()`: 사용 가능한 장치의 수를 반환한다.
* `acc_set_device_type()`: 사용할 장치 유형을 설정한다.
* `acc_get_device_type()`: 현재 설정된 장치 유형을 반환한다.
* `acc_set_device_num()`: 사용할 장치의 번호를 설정한다.
* `acc_get_device_num()`: 현재 설정된 장치의 번호를 반환한다.
* `acc_async_test()`: 지정된 비동기 작업이 완료되었는지 확인한다.
* `acc_async_test_all()`: 모든 비동기 작업이 완료되었는지 확인한다.
* `acc_async_wait()`: 지정된 비동기 작업이 완료될 때까지 기다린다.
* `acc_async_wait_all()`: 모든 비동기 작업이 완료될 때까지 기다린다.
* `acc_init()`: OpenACC 런타임을 초기화한다.
* `acc_shutdown()`: OpenACC 런타임을 종료한다.
* `acc_on_device()`: 코드가 지정된 장치에서 실행 중인지 확인한다.
* `acc_malloc()`: 지정된 장치에 메모리를 할당한다.
* `acc_free()`: 지정된 장치에 할당된 메모리를 해제한다.
OpenACC는 일반적으로 대상 장치에 대한 작업 구성을 처리하지만, 갱(gang)과 워커(worker)를 사용하여 이를 재정의할 수 있다. 갱은 워커로 구성되며, 여러 처리 요소에서 작동한다( OpenCL의 작업 그룹과 유사).