Diberikan kode program di bawah. Jika OMP_SCHEDULE=static, dan nilai max yang dimasukkan adalah 14, manakah jawaban di bawah yang benar (hint: sleep(1) akan membuat thread sleep selama 1 detik):
#include <stdio.h>#include <unistd.h>#include <omp.h>int main (int argc , char *argv []) { int max; sscanf (argv [1], "%d", &max); long int sum = 0; #pragma omp parallel for reduction (+: sum) schedule(runtime) for (int i = 1; i <= max; i++) { printf ("%2d @ %d\n", i, omp_get_thread_num()); sleep (i < 4 ? i + 1 : 1); sum = sum + i; } printf ("%ld\n", sum); return 0;}
a. Thread dengan rank 0 akan berjalan selama 10 detik
b. Thread dengan rank 1 akan berjalan selama 5 detik
c. Thread dengan rank 2 akan berjalan selama 4 detik
d. Thread dengan rank 3 akan berjalan selama 2 detik
e. Tidak ada jawaban yang benar
Jawaban: a. Thread dengan rank 0 akan berjalan selama 10 detik
Penjelasan:
Dengan schedule(static) tanpa chunk size dan 4 thread (berdasarkan opsi jawaban), 14 iterasi akan dibagi sebagai berikut:
Thread 0: Mengerjakan iterasi 1, 2, 3, 4.
Thread 1: Mengerjakan iterasi 5, 6, 7, 8.
Thread 2: Mengerjakan iterasi 9, 10, 11.
Thread 3: Mengerjakan iterasi 12, 13, 14.
Waktu eksekusi untuk setiap iterasi i adalah sleep(i < 4 ? i + 1 : 1).
Jadi, pernyataan yang benar adalah Thread 0 berjalan selama 10 detik.
2. Analisis Kode CUDA
Diberikan kode CUDA berikut (array_size adalah ukuran array a dan b, num_threads adalah jumlah total threads (blockDim.x * gridDim.x)). Manakah jawaban di bawah ini yang benar:
__device__ void prob(int array_size) { int tid = threadIdx.x + blockIdx.x * blockDim.x; for ( int i=tid; i<array_size; i += num_threads ) result[i] = a[i] + b[i];}
a. Akses memori pada kode di atas tidak coalesced
b. Kode di atas sudah menangani boundary condition dengan sesuai
c. Jika ukuran blok diperbesar maka eksekusinya akan lebih cepat
d. Code divergence pada eksekusi kode di atas mengakibatkan eksekusinya tidak optimal
e. Pemanfaatan shared memory akan membuat eksekusi kode tersebut lebih cepat
Jawaban: b. Kode di atas sudah menangani boundary condition dengan sesuai
Penjelasan:
Pola perulangan for (int i=tid; i<array_size; i += num_threads) dikenal sebagai grid-stride loop. Pola ini sangat bagus karena kondisi i < array_size memastikan tidak ada akses memori di luar batas array, tidak peduli berapa banyak thread yang diluncurkan.
3. Analisis Kode MPI
Diberikan pseudocode MPI berikut. Manakah jawaban di bawah ini yang benar jika program tersebut dijalankan dengan 1 proses?
MPI_INIT ()MPI_COMM_RANK (MPI_COMM_WORLD, myrank, ierr)if (myrank == 1) MPI_SEND (some data to processor 2 in MPI_COMM_WORLD)else { MPI_RECV (data from processor 1 in MPI_COMM_WORLD) print "Message received!"}MPI_FINALIZE()
a. Hasil eksekusi “Message received!” dan program selesai
b. Program akan selesai normal tanpa output
c. Program akan hang tanpa output
d. Muncul error
e. Tidak ada jawaban di atas yang benar
Jawaban: c. Program akan hang tanpa output
Penjelasan:
Saat program dijalankan dengan 1 proses, myrank akan bernilai 0. Program akan masuk ke blok else dan memanggil MPI_RECV yang menunggu kiriman data dari proses rank 1. Karena proses rank 1 tidak ada, tidak akan ada yang mengirim data. Akibatnya, MPI_RECV akan menunggu selamanya, dan program akan hang.
4. Semantik MPI_SEND
MPI_SEND digunakan untuk mengirim data array yang berukuran besar. Saat pemanggilan MPI_SEND selesai, programmer dapat mengasumsikan bahwa:
a. Proses destinasi telah menerima data tersebut
b. Array telah dikopi ke internal buffer
c. Array masih belum tentu telah dikopi ke internal buffer
d. Salah satu dari A atau B
e. Tidak ada jawaban di atas yang benar
Jawaban: c. Array masih belum tentu telah dikopi ke internal buffer
Penjelasan:
MPI_SEND adalah operasi blocking standar. Ketika fungsi ini returned, ini cuma menjamin bahwa buffer pengirim aman untuk digunakan kembali. MPI tidak memberikan jaminan bagaimana ini dicapai. Bisa jadi implementasi MPI menunggu sampai MPI_RECV yang cocok siap untuk menerima (perilaku sinkron). Oleh karena itu, kita tidak bisa berasumsi data sudah disalin ke buffer internal.
5. Analisis Kode Reduksi OpenMP
Diberikan kode berikut. Manakah jawaban berikut yang benar?
for (int d = 1; d < ts; d = d * 2) #pragma omp parallel for for (int t = 0; t < ts; t = t + 2 * d) if (t + d < ts) sums[t] = sums[t] + sums[t + d];
a. Kode di atas menghitung reduksi penjumlahan dan hasilnya disimpan pada sums[0]
b. Kode di atas menghitung reduksi penjumlahan dan hasilnya disimpan pada sums[ts]
c. Kode di atas menghitung nilai 2 pangkat ts dan hasilnya disimpan pada sums[0]
d. Kode di atas menghitung nilai 2 pangkat ts dan hasilnya disimpan pada sums[d]
e. Kode di atas menghitung nilai 2 pangkat ts dan hasilnya disimpan pada sums[ts]
Jawaban: a. Kode di atas menghitung reduksi penjumlahan dan hasilnya disimpan pada sums[0]
Penjelasan:
Ini adalah algoritma reduksi paralel klasik di mana pada setiap iterasi, elemen-elemen dijumlahkan dengan “pasangan”-nya yang berjarak d. Proses ini berlanjut hingga semua nilai terakumulasi di elemen pertama array, yaitu sums[0].
6. Konsep Arsitektur Paralel
Pernyataan I: Salah satu paralelisasi menggunakan komputer kelas SIMD adalah dengan memanfaatkan vector processor…
SEHINGGA
Pernyataan II: Pemrograman paralel pada arsitektur SIMD dapat dilakukan dengan memanfaatkan komunikasi antar-proses melalui message passing…
a. I & II keduanya benar dan berhubungan
b. I & II keduanya benar dan tidak berhubungan
c. I benar, II salah
d. I salah, II benar
e. I & II keduanya salah
Jawaban: c. I benar, II salah
Penjelasan:
Pernyataan I benar. Arsitektur SIMD (Single Instruction, Multiple Data) dieksekusi dengan satu instruksi pada banyak data, dan vector processor adalah contoh implementasinya.
Pernyataan II salah. Message passing adalah model pemrograman untuk arsitektur MIMD (Multiple Instruction, Multiple Data), bukan SIMD.
7.Critical SectionpadaLinked List
Diberikan suatu linked list, manakah dari kasus di bawah ini yang bila dilakukan secara paralel berpotensi mengakibatkan masalah terkait critical section?
a. Dua pemanggilan IsMember.
b. Proses Insert dan Delete.
c. Proses Delete dan IsMember.
d. Proses IsMember dan Insert.
e. Dua proses Delete.
Jawaban: b, c, d, dan e semuanya benar, tetapi b (Proses Insert dan Delete) dan e (Dua proses Delete) adalah contoh konflik tulis-tulis yang paling parah.
Penjelasan:
Critical section diperlukan ketika setidaknya satu thread melakukan operasi tulis (Insert, Delete).
(a) Dua operasi baca (IsMember) aman dilakukan secara paralel.
(b, c, d, e) Semua kombinasi yang melibatkan Insert atau Delete berpotensi menimbulkan masalah karena struktur list sedang dimodifikasi saat thread lain mencoba membaca atau memodifikasinya juga.
8. Perbandingan critical vs atomic di OpenMP
Periksalah kedua kode program di bawah ini dan pilihlah pernyataan-pernyataan yang benar!
/* I */ /* II */int count = 0; int count = 0;#pragma omp critical #pragma omp atomiccount++; count++;
Bila lingkungan implementasi dan cakupan program sama, kedua kode program di atas memberikan keadaan hasil yang sama untuk variabel count.
Program yang dibuat menggunakan kode I mengakibatkan eksekusi yang lebih cepat daripada kode II bila dijalankan pada lingkungan yang sama.
Kode program II lebih baik bila digunakan untuk operasi yang lebih kompleks.
Program dapat dioptimalkan dengan menggunakan kedua atribut pragma sekaligus.
Jawaban: Pernyataan 1 adalah yang benar.
Penjelasan:
Pernyataan 1 (Benar): Keduanya akan memastikan count++ dieksekusi secara atomik dan menghasilkan nilai akhir yang benar.
Pernyataan 2 (Salah):atomic (II) umumnya lebih cepat daripada critical (I) karena dapat menggunakan instruksi hardware khusus.
Pernyataan 3 (Salah):critical (I) lebih baik untuk operasi yang lebih kompleks (melindungi blok kode), atomic (II) hanya untuk satu instruksi.
Pernyataan 4 (Salah): Tidak bisa menggunakan keduanya sekaligus.
Soal 9 dan 10
Periksa kode program yang menggunakan MPI di bawah ini dan jawablah pertanyaan di bawah!
// ... (kode kalkulasi local_sum)// Hitung rata-rata dan simpan di global sumfloat global_sum;(I) _____(&local_sum, &global_sum, 1, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD);float mean = global_sum / (num_elements_per_proc * process_size);// ... (kode kalkulasi local_square_diff)// Hitung global sum sebelum dihitung nilai akarnyafloat global_square_diff;(II) ______(&local_square_diff, &global_square_diff, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD);// ... (kode kalkulasi stddev di rank 0)
9. Komunikasi MPI untuk Kalkulasi Rata-rata
Untuk bagian I pada kode program, komunikasi antar proses dapat dilakukan dengan pemanggilan…
a. MPI_GATHER
b. MPI_SCATTER
c. MPI_REDUCE
d. MPI_ALLREDUCE
e. MPI_ALLGATHER
Jawaban: d. MPI_ALLREDUCE
Penjelasan:
Karena mean dibutuhkan oleh semua proses untuk perhitungan local_square_diff di langkah selanjutnya, maka hasil penjumlahan global (global_sum) harus didistribusikan ke semua proses. MPI_ALLREDUCE melakukan reduksi dan menyebarkan hasilnya ke semua proses.
10. Komunikasi MPI untuk Agregasi Akhir
Untuk bagian II pada kode program, komunikasi antar proses dapat dilakukan dengan pemanggilan…
a. MPI_GATHER
b. MPI_SCATTER
c. MPI_REDUCE
d. MPI_ALLREDUCE
e. MPI_ALLGATHER
Jawaban: c. MPI_REDUCE
Penjelasan:
Variabel global_square_diff hanya digunakan oleh satu proses (rank 0) untuk menghitung hasil akhir. MPI_REDUCE melakukan reduksi dan mengirimkan hasil akhirnya hanya ke satu proses root.
11. Kalkulasi Kinerja Pipelining
Jika diketahui CPI = 1/3, Panjang cycle = 7 dengan waktu 10⁻⁹ nano-second per instruksi… Maka waktu yang diperlukan untuk memproses array berisi 6000 elemen adalah:
a. 14.000 x 10⁻⁹
b. 6.006 x 10⁻⁹
c. 2.006 x 10⁻⁹
d. 42.000 x 10⁻⁹
e. Tidak ada jawaban yang benar
Jawaban: a. 14.000 x 10⁻⁹
Penjelasan:
Asumsi yang paling masuk akal adalah “waktu per cycle = 7 nanosecond” (7 x 10⁻⁹ detik).
Diberikan potongan program MPI seperti berikut. Kemungkinan yang akan terjadi adalah:
if (rank==0) { MPI_Send(msg1 to process 1); MPI_Recv(msg2 from process 1);}if (rank==1) { MPI_Send(msg2 to process 0); MPI_Recv(msg1 from process 0);}
a. Proses 1 menerima msg1, setelah itu proses 0 menerima msg2.
b. Proses 0 menerima msg2, setelah itu proses 1 menerima msg1.
c. Proses 0 dan 1 menerima msg1 dan msg2 secara bersamaan
d. Proses 0 dan 1 tidak menerima apapun karena deadlock
e. Tidak ada jawaban yang benar.
Jawaban: d. Proses 0 dan 1 tidak menerima apapun karena deadlock
Penjelasan:
Ini adalah kasus deadlock klasik. Kedua proses memanggil MPI_Send dan akan saling menunggu lawannya memanggil MPI_Recv, yang tidak akan pernah terjadi karena keduanya terjebak pada Send.
13. Analisis OpenMP single dan task
Jika diberikan kode berikut, maka output yang mungkin adalah (asumsi program dieksekusi dengan 2 threads).
b. “Mulai task1 task2 selesai mencetak” (dicetak sebanyak 2 kali)
c. “Mulai task2 task1 selesai mencetak”
d. “Mulai selesai mencetak task2 task1”
e. “Mulai selesai mencetak task1 task2” (dicetak sebanyak 2 kali)
Jawaban: d. “Mulai selesai mencetak task2 task1”
Penjelasan:
Satu thread akan masuk ke region single, mencetak “Mulai ”, membuat dua task (yang eksekusinya ditunda), lalu langsung mencetak “selesai mencetak “. Setelah itu, kedua task dieksekusi dengan urutan yang tidak dijamin. Oleh karena itu, output seperti pada pilihan (d) sangat mungkin terjadi.
14. Scope Variabel CUDA
Pada CUDA, jika deklarasi variabel dengan device tanpa diikuti oleh shared atau constant, maka variabel tersebut:
a. Berada di shared memory dan mempunyai life time sama dengan lifetime thread
b. Berada di constant memory dan mempunyai life time sama dengan lifetime block
c. Berada di global memory dan mempunyai life time sama dengan lifetime block
d. Berada di global memory dan mempunyai life time sama dengan lifetime aplikasi
e. Tidak ada jawaban benar
Jawaban: d. Berada di global memory dan mempunyai life time sama dengan lifetime aplikasi
Penjelasan:
Variabel yang dideklarasikan dengan device di file scope (di luar fungsi) akan dialokasikan di global memory GPU. Memori ini persisten selama aplikasi berjalan.
15. Analisis Divergensi pada Tiling CUDA
Diketahui matrix berukuran 104x104, dibuat tiling berukuran 16x16 dalam satu thread block. Asumsi 1 warp berukuran 32 threads. Jika dilakukan operasi matrix dengan pendekatan tiling maka tentunya akan terjadi control divergensi. Setelah dilakukan analisa ternyata terjadi penurunan performansi sebesar (diharapkan tidak lebih dari):