병렬 프로그래밍은 동시에 수행되는 여러 개의 프로세스와 스레드들을 안전하고 효율적으로 다루는 문제라고 할 수 있다. 프로세스는 독립적인 메모리 공간을 가지고 있기 때문에, 이들이 공유 메모리를 통한 자료 교환을 하지 않는다면, 동기화 문제는 상대적으로 간단한 것이 된다. 그러나, 스레드는 한 프로세스 내에서 실행되며, 스레드는 같은 메모리 공간을 공유하기 때문에 스레드들의 자원 사용 문제는 훨씬 복잡하다.
이러한 문제를 해결한 좋은 라이브러리나 운영체제 차원에서의 지원이 이미 일반화되어 있지만, 멀티스레딩 프로그래밍은 API 몇 개만 호출하는 것으로 간단히 구현되는 것은 아니다. 더구나, 스레드는 성능 문제 때문에 각 플랫폼에서 제공하는 스레드 라이브러리를 사용하기 마련이고, 이들의 서로 다른 스레드 정책들은 멀티스레딩 프로그래밍의 진입 장벽을 높히는 요소가 된다.
OpenMP는 이런 문제에 대한 언어적인 대안이다. OpenMP는 컴파일 지시자를 사용하여 컴파일 단계에서 구조적인 스레딩 코드를 생성한다. Win32 스레드나 pthread나 새로운 스레드를 기동하는 과정은 간단한 편은 아닌데, OpenMP는 이 과정을 컴파일 지시자를 통해 기계적으로 자동화하며, 멀티스레딩 환경에서의 동작을 제어할 수 있는 수단을 제공한다. 이것은 스레드 프로그래밍을 하면서 발생하기 쉬운 각종 버그들을 미연에 방지하는 효과도 있다. 스레드 지원 함수들이 사용하기가 쉬운 편이 아니기 때문에, 프로그래머가 이들을 사용하여, 멀티스레딩 상황에서 직접 자료구조에 대한 안전성을 보장하는 코드를 작성하는 것은 쉬운 일이 아니다. 따라서, 기계적으로 안전성을 보장해주는 이런 메커니즘은 매우 유용하다. 특히, 멀티스레딩 환경에서의 버그는 재현하기가 거의 불가능하기 때문에, 디버깅이 매우 어렵다는 점을 고려하면 더욱 그렇다. OpenMP는 컴파일러 차원에서 #pragma 지시자를 통해 코드를 생성하고, 스레드 안전성을 기계적으로 보장하며, 이미 유명한 컴파일러들이 OpenMP를 지원하고 있기 때문에 이식성이 매우 뛰어나다. Visual C++ 8.0 이상, gcc 4.3 이상이라면 OpenMP 2.0 규격을 지원한다. 멀티스레딩이 일반화되는 시대가 된다면, 표준에 포함될 가능성도 있다. 물론, 여기서 말하는 일반화란, 초보자들을 위한 입문서에도 멀티스레딩 코드 작성을 위한 챕터가 실릴 정도로 널리 쓰여지는 것을 말한다.
다만, OpenMP가 마냥 좋기만 한 것은 아니다. OpenMP는 쉽게 멀티스레딩 프로그래밍을 할 수 있도록 도와주기는 하지만, pthread와 같은 라이브러리에서 제공하는 수준의 세밀한 제어는 지원되지 않는다. 더구나, 예외를 처리하는 기능이 극히 미약하다는 것과, 병렬화가 용이한 자료구조에 대해서만 최대의 효과가 있다는 점은 약점이다. 그리고, 위에서 말한 스레드 안전성을 기계적으로 보장한다는 것도, 문맥적인 의미에서 안전성을 보장한다는 것이지, 행복한 공짜 점심을 의미하는 것은 아니다. 또, OpenMP를 사용하여 기동한 스레드는, 다른 스레드 라이브러리가 생성한 스레드를 알 수 없다. 예를 들어, Win32 플랫폼에서 OpenMP는 내부적으로 Win32 스레드 위에 구현되어 있기 때문에서 서로 잘 동작한다. 하지만, 직접 기동시킨 Win32 스레드와 OpenMP로 기동된 스레드는 서로의 존재를 알 수 없기 때문에 동기화 문제가 발생할 수 있다. MinGW의 libgomp의 경우, pthread를 필요로 하지만 OpenMP의 스레드팀에서 생성된 스레드들에 대해 직접 pthread 동기화를 적용할 수 없다.
그러나, 이런 단점을 보완해줄 인프라를 가지고 있다면, OpenMP는 멀티스레딩 프로그래밍에 부스터를 달아주는 듯한 효과를 줄 것이다. OpenMP는 현재 C/C++, 포트란을 지원한다.
Reference
http://www.openmp.org/
https://computing.llnl.gov/tutorials/openMP/
http://msdn.microsoft.com/en-us/magazine/cc163717.aspx