Presentasi sedang didownload. Silahkan tunggu

Presentasi sedang didownload. Silahkan tunggu

8.1. Multiprosesor Memori Bersama 8.2. Membangun Kepararelan Khusus Membuat Proses Simultan Threads Pengolahan Paralel/KK0212398/1/51 8. Pemrograman Dengan.

Presentasi serupa


Presentasi berjudul: "8.1. Multiprosesor Memori Bersama 8.2. Membangun Kepararelan Khusus Membuat Proses Simultan Threads Pengolahan Paralel/KK0212398/1/51 8. Pemrograman Dengan."— Transcript presentasi:

1 8.1. Multiprosesor Memori Bersama 8.2. Membangun Kepararelan Khusus Membuat Proses Simultan Threads Pengolahan Paralel/KK0212398/1/51 8. Pemrograman Dengan Memori Bersama 8.3. Data yang Digunakan Bersama Membuat Data Yang Digunakan Bersama Mengakses Data Yang Digunakan Bersama Konstruksi Bahasa untuk Kepararelan Analisis Ketergantungan Data yang Digunakan Bersama dalam Sistem dengan Cache 8.4. Contoh Program Pemrosesan dalam UNIX Contoh dengan JAVA Referensi : Wilkinson, B, Parallel Programming, Chapter 8, hal. 227-263

2 Setiap lokasi memori dapat diakses oleh prosesor manapun. Sebuah Ruang alamat tunggal terjadi, ini berarti bahwa setiap lokasi memori diberikan alamat tunggal/unik diantara area tunggal suatu alamat. Pengolahan Paralel/KK021239 Sistem Multiprosesor Dengan Memori Bersama Untuk sejumlah kecil prosesor, arsitektur umumnya adalah arsitektur bus tunggal : 8/2/51

3 Gambar 8.1 Shared Memory Multiprocessor menggunakan Bus Tunggal Pengolahan Paralel/KK0212398/3/51

4 Menggunakan bahasa pemrograman baru Memodifikasi bahasa sekuensial yang ada Menggunakan rutin library dengan bahasa sekuensial yang ada Menggunakan bahasa pemrograman sekuensial yang ada dan perintahkan kompiler paralel untuk mengkonversinya ke dalam kode yang dapat dieksekusi secara paralel Pemrosesan UNIX Threads (Pthreads, Java, …) Beberapa Alternatif Pemrograman Pengolahan Paralel/KK0212398/4/51

5 TABEL 8.1 Beberapa Bahasa Pemrograman Paralel Pengolahan Paralel/KK0212398/5/51

6 Membuat Proses Simultan - Konstruksi FORK-JOIN Membangun Kepararelan Khusus Gambar 8.2 Konstruksi FORK-JOIN Pengolahan Paralel/KK0212398/6/51

7 Sistem UNIX memanggil fork() untuk membuat sebuah proses baru. Proses baru (child process) adalah suatu salinan eksak dari suatu pemanggilan proses kecuali apabila proses baru tersebut mempunyai ID proses unik. Child process mempunyai salinannya sendiri dari varibel parent- nya. Variabel parent diberikan nilai yang sama seperti variabel original pada saat proses inisialisasi. Proses fork memulai eksekusi pada saat titik fork. Pemrosesan Heavyweight UNIX Apabila proses fork tersebut berhasil, fork() return ()kepada child process dan return ID proses dari child process ke parent process. Proses-proses tersebut digabungkan (join) dengan pemanggilan sistem wait () dan exit(), yang didefinisikan sebagai berikut : Pengolahan Paralel/KK0212398/7/51

8 wait(statusp); /*delays caller until signal received or one of its */ /*child processes terminates or stops */ exit(status); /*terminates a process. */ Sebuah Child Process dapat dibuat melalui : pid = fork(); /* fork */ Kode akan dieksekusi oleh child dan parent if (pid == 0) exit(0); else wait(0); /* join */ Pengolahan Paralel/KK0212398/8/51

9 pid = fork(); Jika sebuah child untuk mengeksekusi kode yabg berbeda, dapat menggunakan : if (pid == 0) { Kode akan dieksekusi oleh slave } else { } if (pid == 0) exit(0); else wait(0); Kode akan dieksekusi oleh parent Pengolahan Paralel/KK0212398/9/51

10 Threads Proses “heavyweight”- benar- benar program terpisah dengan Variabelnya sendiri, stack, dan Alokasi memori Threads - Secara bersama-sama Membagi ruang memori yang sama dan variabel global diantara rutin-rutin Pengolahan Paralel/KK0212398/10/51

11 IEEE Portable Operating System Interface, POSIX, section 1003.1 standard Pthreads: Gambar 8.4 pthread_create() and pthread_join(). Pengolahan Paralel/KK0212398/11/51

12 Pthread Barrier Rutin pthread_join() menunggu satu thread tertentu untuk mengakhiri/terminasi. Untuk membuat satu barrier menunggu seluruh threads, pthread_join() dapat diulang : for (i = 0; i < n; i++) pthread_create(&thread[i], NULL, (void *) slave, (void *) &arg); for (i = 0; i < n; i++) pthread_join(thread[i], NULL); Pengolahan Paralel/KK0212398/12/51

13 Detached Threads Dapat saja terjadi bahwa thread tidak terganggu ketika satu thread terminasi dan pada kasus tersebut join tidak diperlukan. Threads yang tidak di-join disebut sebagai detached threads. Gambar 8.5 Detached threads. Pengolahan Paralel/KK0212398/13/51

14 Urutan Eksekusi Perintah Pada suatu sistem multiprosesor, instruksi dari suatu proses/ thread dapat saja berselangan waktunya. Contoh Proses 1 Proses 2 Instruction 1.1 Instruction 2.1 Instruction 1.2 Instruction 2.2 Instruction 1.3 Instruction 2.3 Ada beberapa urutan yang memungkinkan, termasuk : Instruction 1.1 Instruction 1.2 Instruction 2.1 Instruction 1.3 Instruction 2.2 Instruction 2.3 Diasumsikan satu instruksi tidak dapat dibagi ke dalam langkah yang lebih kecil Pengolahan Paralel/KK0212398/14/51

15 Jika dua proses mencetak pesan, sebagai contoh, pesan tersebut dapat muncul dalam urutan yang berbeda tergantung kepada penjadwalan dari pemanggilan proses dari rutin pencetakan. Keadaan terburuk adalah, setiap karakter dari pesan tersebut dapat berselang jika instruksi mesin dari rutin pencetakan dapat berselang. Pengolahan Paralel/KK0212398/15/51

16 Optimasi Kompiler/Prosesor Kompiler (atau prosesor) dapat mengurutkan kembali instruksi untuk keperluan optimasisasi. Contoh Pernyataan a = b + 5; x = y + 4; dapat dikompilasi untuk mengeksekusi dalam urutan terbalik : x = y + 4; a = b + 5; dan masih benar secara logik. Akan sangat menguntungkan apabila men-delay pernyataan a = b + 5 karena beberapa instruksi sebelumnya yang masih/sedang dieksekusi oleh prosesor memerlukan lebih banyak waktu untuk menghasilkan nilai untuk b. Pengolahan Paralel/KK0212398/16/51

17 Rutin Thread-Safe Pemanggilan sistem atau rutin libarari disebut sebagai thread safe dapat dipanggil dari thread multipel secara simultan dan selalu menghasilkan hasil and selalu menghasilkan hasil yang benar. Contoh Standard I/O thread safe (mencetak pesan tanpa mengacaukan karakternya). Rutin yang mengakses data bersama/statis memerlukan perhatian yang khusus agar dapat membuat suatu thread safe. Pengolahan Paralel/KK0212398/17/51

18 8/3jml. Slide Mengakses Data Bersama Dimisalkan ada 2 proses, dimana satu proses berfungsi untuk menambah nilai 1 ke dalam item data bersama, x. Diperlukan pembacaan untuk isi dari lokasi x, hasil perhitungan x + 1 dan hasil penulisan kembali ke lokasi semula. Dengan 2 proses melakukan hal tersebut pada saat yang sama, maka didapat : Instruction Process 1 Process 2 x = x + 1; read x read x compute x+1 compute x +1 write to x Time Pengolahan Paralel/KK0212398/18/51

19 Gambar 8.6 Konflik dalam Pengaksesan variabel Bersama Pengolahan Paralel/KK0212398/19/51

20 Bagian Kritis Suatu mekanisme untuk menentukan bahwa hanya satu proses mengakses resource tertentu pada satu waktu adalah dengan membentuk bagian dari kode yang terlibat dalam resource tersebut disebut sebagai Bagian Kritis (Critical Sections) dan mengatur bahwa hanya satu bagian kritis yang dieksekusi pada satu waktu. Apabila satu proses telah selesai menyelesaikan bagian kritisnya, maka proses lain diijinkan untuk memasuki bagian kritis untuk resource yang sama. Mekanisme tersebut dikenal sebagai mutual exclusion. Pengolahan Paralel/KK0212398/20/51

21 LOCK adalah mekanisme sederhana untuk memastikan mutual exclusion dari suatu bagian kritis (critical section) Suatu lock adalah variabel 1-bit dimana angka 1 mengindikasikan bahwa satu proses telah masuk ke bagian kritis dan satu () mengindikasikan bahwa tidak ada proses di dalam bagian kritis. Suatu lock beroperasi seperti penguncian suatu pintu. Suatu proses menuju ke suatu “pintu” dari bagian kritis dan menemukan “pintu” yang terbuka maka diperbolehkan masuk ke bagian kritis, kemudian mengunci pintunya agar menhindari proses lain yang ingin masuk. Setelah proses selesai, maka pintunya dibuka (unlock) dan meninggalkannya. Pengolahan Paralel/KK0212398/21/51

22 SPIN LOCK Contoh while (lock == 1) do_nothing; /* no operation in while loop */ lock = 1; /* enter critical section */. critical section. lock = 0; /* leave critical section */ Pengolahan Paralel/KK0212398/22/51

23 Gambar 8.7 Mengontrol bagian kritis melalui busy waiting. Pengolahan Paralel/KK0212398/23/51

24 Deadlock Deadlock dapat terjadi dengan 2 proses, dimana proses yang satu memerlukan satu resource yang sedang digunakan oleh yang lainnya, dan proses ini memerlukan resource yang digunakan oleh proses pertama. Gambar 8.8 Deadlock (deadly embrace). Pengolahan Paralel/KK0212398/24/51

25 Dapat saja terjadi suatu dealock yang circular, dimana beberapa proses mempunyai resource yang diinginkan oleh proses lainnya. Gambar 8.8 Deadlock n-proses Pengolahan Paralel/KK0212398/25/52

26 Semaphores Suatu semaphore, s (say), adalah satu bilangan bulat positif (termasuk nol) yang dioperasikan pada dua operasi yang diberi nama p dan v. Operasi p, p (s) menunggu sampai s lebih besar dari 0 (nol) dan kemudian mengurangi s dengan 1 (satu) dan mengijinkan proses untuk berlanjut. Operasi v, v (s) menambah s dengan 1 (satu) untuk melepaskan satu proses yang menunggu (bila memang ada). Operasi p dan v dilaksanakan secara individu. Proses yang di- delay oleh p (s) disimpan dalam suatu abeyance sampai dilepaskan oleh v (s) pada semaphore yang sama. Pengolahan Paralel/KK0212398/26/51

27 Mutual Exclusion dari Bagian Kritis (Critical Section) : Dapat dicapai dengan satu semaphore yang mempunyai nilai 0 atau 1 (binary semaphore), yang bertindak sebagai satu variabel lock, tetapi operasi p dan v termasuk mekanisme proses penjadwalan. Semaphore diinisialisasi dengan 1, mengindikasikan bahwa tidak ada proses di dalam bagian kritis yang berasosiasi dengan semaphore. Pengolahan Paralel/KK0212398/27/51

28 General Semaphores : Dapat diambil pada nilai positif selain 0 (nol) dan 1 (satu). Rutin semaphore terdapat untuk proses dalam UNIX. Tetapi rutin tersebut tidak terdapat dala Ptread. Monitor Suatu prosedur yang menyediakan metode untuk mengakses resource bersama. (shared resource). Data dan operasi yang dapat beroperasi pada suatu data adalah terenkapsulasi ke dalam satu struktur. Membaca dan menulis hanya dapat dilakukan denganmenggunakan prosedur monitor, dan hanya satu proses dapat menggunakan prosedur pada satu saat. Pengolahan Paralel/KK0212398/28/51

29 Satu prosedur monitor dapat diimplementasikan menggunakan semaphore untuk melindungi entri-nya. Contoh monitor dengan Java : Pengolahan Paralel/KK0212398/29/51

30 Operasi Variabel Kondisi Wait(cond_var) Kondisi menunggu terjadi Signal(cond_var) Sinyal yang kondisinya terjadi Status(cond_var) Return jumlah proses menunggu yang terjadi. Operasi wait juga akan melepaskanlock atau semaphoredan dapat digunakan untuk mengijinkan proses lain masuk ke dalam kondisi. Contoh : Umpamakan satu atau lebih proses (atau thread) didesain untuk mengambil aksi ketika satu kaunter, x, adalah nol (0). Proses atau thread lain bertanggungjawab untuk mengurangi kaunter. Pengolahan Paralel/KK0212398/30/51

31 Rutin dapat berbentuk sebagai berikut : Pengolahan Paralel/KK0212398/31/51

32 Konstruksi Bahasa untuk Kepararelan Data Bersama Variabel memori bersama dapat dideklarasikan sebagai bersama (shared), katakan sebagai : shared int x; Konstruksi Paralel : par Untuk menspesifikasikan perintah yang simultan : par { S1; S2;. Sn; } Pengolahan Paralel/KK0212398/32/51

33 Konstruksi forall Untuk memulai proses sejenis yang serupa secara bersama-sama : Forall (I=0; I < n; I++) { S1; S2;. Sm; } Yang menghasilkan proses n, dimana masing-masingnya berisi perintah yang membentuk tubuh dari loop for, s1,s2, …,sm. Setiap proses mengubakan nilai yang berbeda dari i. Contoh : forall (i = 0; i < 5; i++) a[i] = 0; Membersihkan a[0], a[1], a[2], a[3], dan a[4] menjadi nol secara simultan. Pengolahan Paralel/KK0212398/33/51

34 Analisis Ketergantungan Untuk mengidentifikasi proses mana yang dapat dieksekusi secara bersama-sama : Contoh : Forall (i=0; i < 5; i++) a[i] = 0; Topi setiap instant dari tubuh adalah independen dari instant lain dan semua instant dapat dieksekusi secar simultan. Bagaimanapun juga hal tersebut tidak begitu jelas. Memerlukan cara algoritma dalam mengenalkan ketergantunga untuk kompiler paralel. Pengolahan Paralel/KK0212398/34/51

35 Kondisi Bernstein Himpunan kondisi yang cukup untuk menentukan apakah 2 proses dapat dieksekusi secara simultan. Mari kita mendefinisikan 2 buah himpunan berikut ini : Ii adalah himpunan dari lokasi memori yang dibaca oleh proses Pi. Oj adalah himpunan dari lokasi memori yang dimasuki oleh proses Pj. Untuk dua proses P 1 dan P 2 yang akan dieksekusi secara simultan input untuk proses P 1 harus bukan bagian dari output dari P 2 dan input dari P 2 harus bukan bagian dari output dari P 1 misalnya : Pengolahan Paralel/KK0212398/35/51

36 Dimana  adalah himpunan kosong. Himpunan output dari tiap proses harus berbeda. Misalnya : Jika tiga kondisi terpenuhi, dua proses dapat dieksekusi secara simultan Contoh : Misalkan 2 perintah (dalam C) berikut ini : a = x + y; b = x + z; Pengolahan Paralel/KK0212398/36/51

37 Kita mempunyai : I 1 = (x, y) O 1 = (a) I 2 = (x, z) O 2 = (b) Dan kondisi : Adalah terpenuhi. Maka perintah a = x+y dan b =x+z dapat dieksekusi secara simultan. Pengolahan Paralel/KK0212398/37/51

38 Data Bersama dalam Sistem dengan Cache Semua komputer modern mempunyai memori cache, memori berkecepatan tinggi sangat lekat dengan prosesor untuk menangani data referansi dan kode terkini. Protokol Koheren Cache Dalam kebijaksanaan update, salinan data dalam semua cache dimodifikasi pada saat satu salinan masuk. Dalam kebijaksanaan invalidate, ketika satu salinan data dimasukan, data yang sama pada cache lain di-invalidate (melalui pe-reset-an kembali satu bit yang valid dalam cache). Salinan tersebut hanya dimodifikasi ketika prosesor yang berasosiasi membuat referensi untuk itu. Pengolahan Paralel/KK0212398/38/51

39 False Sharing Bagian yang berbeda dari blok dibutuhkan oleh prosesor yang berbeda tetapi byte-nya tidak sama. Jika satu prosesor menulis satu bagian dari blok, salinan dari blok komplit dalam cache berbeda harus sudah dimodifikasi atau di -invalidate- melalui data yang aktual tidak dapat dibagi bersama. Pengolahan Paralel/KK0212398/39/51

40 Solusi untuk False Sharing Kompiler memasuki layout dari data yang disimpan dalam memori utama, memisahkan data hanya yang dimasukan oleh satu prosesor ke dalam blok yang berbeda. Contoh Program Untuk menjumlahkan elemen dari suatu array, a[1000] : int sum, a[1000]; sum = 0; for (i = 0; i < 1000; i++) sum = sum + a[i]; Pengolahan Paralel/KK0212398/40/51

41 Proses UNIX Kalkulasi akan dibagi menjadi dua bagian, satu melakukan i genap dan yang satu lagi melakukan i ganjil, misalnya : Process 1 Process 2 sum1 = 0; sum2 = 0; for (i = 0; i < 1000; i = i + 2) for (i = 1; i < 1000; i = i + 2) sum1 = sum1 + a[i]; sum2 = sum2 + a[i]; Tiap proses akan menambah hasilnya ( sum1 atau sum2 ) ke satu akumulai hasil, sum : sum = sum + sum1; sum = sum + sum2; Pengolahan Paralel/KK0212398/41/51

42 Gambar 8.10 Lokasi Memori Bersama untuk contoh program UNIX Pengolahan Paralel/KK0212398/42/51

43 #include #define array_size 1000 /* no of elements in shared memory */ extern char *shmat(); void P(int *s); void V(int *s); int main() { int shmid, s, pid; /* shared memory, semaphore, proc id */ char *shm; /*shared mem. addr returned by shmat()*/ int *a, *addr, *sum; /* shared data variables*/ int partial_sum;/* partial sum of each process */ int i; /* initialize semaphore set */ int init_sem_value = 1; s = semget(IPC_PRIVATE, 1, (0600 | IPC_CREAT)) if (s == -1) { /* if unsuccessful*/ perror("semget"); exit(1); } Pengolahan Paralel/KK0212398/43/51

44 if (semctl(s, 0, SETVAL, init_sem_value) < 0) { perror("semctl"); exit(1); } /* create segment*/ shmid = shmget(IPC_PRIVATE,(array_size*sizeof(int)+1), (IPC_CREAT|0600)); if (shmid == -1) { perror("shmget"); exit(1); } /* map segment to process data space */ shm = shmat(shmid, NULL, 0); /* returns address as a character*/ if (shm == (char*)-1) { perror("shmat"); exit(1); } Pengolahan Paralel/KK0212398/44/51

45 addr = (int*)shm; /* starting address */ sum = addr; /* accumulating sum */ addr++; a = addr; /* array of numbers, a[] */ *sum = 0; for (i = 0; i < array_size; i++) /* load array with numbers */ *(a + i) = i+1; pid = fork(); /* create child process */ if (pid == 0) { /* child does this */ partial_sum = 0; for (i = 0; i < array_size; i = i + 2) partial_sum += *(a + i); else { /* parent does this */ partial_sum = 0; for (i = 1; i < array_size; i = i + 2) partial_sum += *(a + i); } P(&s); /* for each process, add partial sum */ *sum += partial_sum; V(&s); Pengolahan Paralel/KK0212398/45/51

46 printf("\nprocess pid = %d, partial sum = %d\n", pid, partial_sum); if (pid == 0) exit(0); else wait(0); /* terminate child proc */ printf("\nThe sum of 1 to %i is %d\n", array_size, *sum); /* remove semaphore */ if (semctl(s, 0, IPC_RMID, 1) == -1) { perror("semctl"); exit(1); } /* remove shared memory */ if (shmctl(shmid, IPC_RMID, NULL) == -1) { perror("shmctl"); exit(1); } } /* end of main */ Pengolahan Paralel/KK0212398/46/51

47 void P(int *s) /* P(s) routine*/ { struct sembuf sembuffer, *sops; sops = &sembuffer; sops->sem_num = 0; sops->sem_op = -1; sops->sem_flg = 0; if (semop(*s, sops, 1) < 0) { perror("semop"); exit(1); } return; } void V(int *s) /* V(s) routine */ { struct sembuf sembuffer, *sops; sops = &sembuffer; sops->sem_num = 0; sops->sem_op = 1; sops->sem_flg = 0; if (semop(*s, sops, 1) <0) { perror("semop"); exit(1); } return; } Pengolahan Paralel/KK0212398/47/51

48 SAMPLE OUTPUT process pid = 0, partial sum = 250000 process pid = 26127, partial sum = 250500 The sum of 1 to 1000 is 500500 Pengolahan Paralel/KK0212398/48/51

49 Contoh JAVA public class Adder { public int[] array; private int sum = 0; private int index = 0; private int number_of_threads = 10; private int threads_quit; public Adder() { threads_quit = 0; array = new int[1000]; initializeArray(); startThreads(); } public synchronized int getNextIndex() { if(index < 1000) return(index++); else return(-1); } Pengolahan Paralel/KK0212398/49/51

50 public synchronized void addPartialSum(int partial_sum) { sum = sum + partial_sum; if(++threads_quit == number_of_threads) System.out.println("The sum of the numbers is " + sum); } private void initializeArray() { int i; for(i = 0;i < 1000;i++) array[i] = i; } public void startThreads() { int i = 0; for(i = 0;i < 10;i++) { AdderThread at = new AdderThread(this,i); at.start(); } { Adder a = new Adder(); } Pengolahan Paralel/KK0212398/50/51

51 public static void main(String args[]) class AdderThread extends Thread { int partial_sum = 0; Adder parent; int number; public AdderThread(Adder parent,int number) { this.parent = parent; this.number = number; } public void run() { int index = 0; while(index != -1) { partial_sum = partial_sum + parent.array[index]; index = parent.getNextIndex(); } System.out.println("Partial sum from thread " + number + " is " + partial_sum); parent.addPartialSum(partial_sum); } Pengolahan Paralel/KK0212398/51/51


Download ppt "8.1. Multiprosesor Memori Bersama 8.2. Membangun Kepararelan Khusus Membuat Proses Simultan Threads Pengolahan Paralel/KK0212398/1/51 8. Pemrograman Dengan."

Presentasi serupa


Iklan oleh Google