OpenMP (Open Multi-Processing) adalah sebuah API (Application Programming Interface) yang dirancang untuk menyederhanakan pemrograman paralel pada sistem shared-memory. Berbeda dengan Pthreads yang bersifat low-level dan manual, OpenMP bekerja pada level yang lebih tinggi, sering kali hanya dengan menambahkan instruksi khusus ke kode serial yang sudah ada. Tujuannya adalah membuat paralelisasi menjadi lebih mudah dan portabel.
Konsep Inti: Pragmas
OpenMP sebagian besar diimplementasikan menggunakan Pragmas.
Definisi: Pragma (#pragma) adalah sebuah direktif atau instruksi khusus untuk compiler. Ini bukan bagian dari standar bahasa C, melainkan ekstensi.
Sifat Elegan: Jika sebuah compiler tidak mengenali atau tidak mendukung OpenMP, ia akan mengabaikan pragma tersebut. Artinya, kode Anda akan tetap bisa dikompilasi dan berjalan sebagai program serial biasa. Ini membuat kode OpenMP sangat portabel.
Direktif Dasar: #pragma omp parallel
Ini adalah direktif paling fundamental di OpenMP. Saat compiler menemukannya, ia akan melakukan hal berikut:
Menandai blok kode terstruktur yang mengikutinya (misalnya, blok {...}).
Membuat sekelompok thread baru (disebut team).
Setiap thread dalam team tersebut akan mengeksekusi blok kode yang sama secara bersamaan.
Alur Eksekusi: Model Fork-Join
Program OpenMP mengikuti model fork-join:
Mulai Serial: Program dimulai dengan satu thread utama, yang disebut master thread.
Fork (Membelah): Saat bertemu #pragma omp parallel, master thread akan “membelah diri” dan membuat beberapa slave threads.
Eksekusi Paralel: Master thread bersama dengan para slave threads membentuk sebuah team dan mengeksekusi blok paralel secara bersamaan.
Join (Bergabung): Di akhir blok paralel, terdapat barrier implisit. Semua thread akan menunggu di sini. Setelah semua thread selesai, para slave threads akan “dihancurkan”, dan hanya master thread yang melanjutkan eksekusi bagian serial berikutnya.
Kompilasi dan Eksekusi
Untuk mengaktifkan OpenMP, kita perlu memberitahu compiler menggunakan flag khusus.
Flag -fopenmp sangat penting; tanpanya, pragma akan diabaikan.
Eksekusi: ./nama_program <jumlah_thread>
Jumlah thread bisa ditentukan melalui klausa num_threads() pada pragma atau melalui environment variableOMP_NUM_THREADS.
Menjaga Kode Tetap Portabel
OpenMP mendefinisikan sebuah makro _OPENMP. Kita bisa menggunakannya untuk menulis kode yang bisa beradaptasi, misalnya untuk memanggil fungsi OpenMP hanya jika OpenMP diaktifkan.
#ifdef _OPENMP // Kode ini hanya akan dikompilasi jika -fopenmp digunakan #include <omp.h> int my_rank = omp_get_thread_num();#else // Fallback untuk kompiler non-OpenMP int my_rank = 0;#endif
Summary
OpenMP adalah API tingkat tinggi yang menyederhanakan pemrograman paralel pada shared memory dengan menggunakan pragmas, di mana direktif inti #pragma omp parallel mengimplementasikan model fork-join untuk mengeksekusi blok kode secara konkuren oleh sebuah team thread. Kode OpenMP bersifat portabel karena compiler non-OpenMP akan mengabaikan pragmas, dan kompilasinya diaktifkan melalui flag -fopenmp.
Additional Information
Contoh Kode: “Hello World”
Berikut adalah program “Hello World” kanonis di OpenMP yang menunjukkan konsep-konsep di atas:
#include <stdio.h>#include <stdlib.h>#include <omp.h> // Header untuk fungsi OpenMPvoid Hello(void); // Prototipe fungsi yang akan dijalankan threadint main(int argc, char* argv[]) { int thread_count = strtol(argv[1], NULL, 10); // Fork: Buat sebuah team dengan 'thread_count' thread. // Setiap thread akan menjalankan fungsi Hello(). #pragma omp parallel num_threads(thread_count) { Hello(); } // Join: Barrier implisit di sini. Master thread menunggu semua slave. return 0;}void Hello(void) { // Fungsi OpenMP untuk mendapatkan ID thread (rank) int my_rank = omp_get_thread_num(); // Fungsi OpenMP untuk mendapatkan total thread dalam team int thread_count = omp_get_num_threads(); printf("Hello from thread %d of %d\n", my_rank, thread_count);}
Output dari program ini tidak akan pernah bisa diprediksi urutannya, karena sistem operasi bebas menjadwalkan eksekusi setiap thread.
Kontrol Jumlah Thread
Selain menggunakan klausa num_threads(count) di dalam kode, Anda juga bisa mengontrol jumlah thread dari luar program menggunakan environment variable. Ini lebih fleksibel karena tidak perlu kompilasi ulang.
# Set variabel OMP_NUM_THREADS ke 8 untuk sesi terminal iniexport OMP_NUM_THREADS=8
# Jalankan program, ia akan menggunakan 8 thread./nama_program
Prioritasnya adalah: num_threads() > OMP_NUM_THREADS > default sistem