• Tidak ada hasil yang ditemukan

Pemrograman shared memori

N/A
N/A
Protected

Academic year: 2018

Membagikan "Pemrograman shared memori"

Copied!
51
0
0

Teks penuh

(1)

8.1. Multiprosesor Memori Bersama 8.2. Membangun Kepararelan Khusus Membuat Proses Simultan

Threads

Pengolahan Paralel/KK021239 8/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

(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 :

(3)

Gambar 8.1 Shared Memory Multiprocessor

menggunakan Bus Tunggal

(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

(5)

TABEL 8.1 Beberapa Bahasa Pemrograman Paralel

(6)

Membuat Proses Simultan - Konstruksi FORK-JOIN

Membangun Kepararelan Khusus

Gambar 8.2 Konstruksi FORK-JOIN

(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 :

(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 */

(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

(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

(11)

IEEE Portable Operating System Interface, POSIX, section 1003.1 standard

Pthreads:

Gambar 8.4

pthread_create() and pthread_join().

(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);

(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.

(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

Diasumsikan satu instruksi tidak dapat dibagi ke dalam langkah yang lebih kecil

(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.

(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.

(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.

(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

write to x

Time

(19)

Gambar 8.6 Konflik dalam Pengaksesan variabel Bersama

(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.

(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.

(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 */

(23)

Gambar 8.7 Mengontrol bagian kritis melalui busy waiting.

(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).

(25)

Dapat saja terjadi suatu dealock yang circular, dimana beberapa proses mempunyai resource yang diinginkan oleh proses lainnya.

Gambar 8.8 Deadlock n-proses

(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.

(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.

(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.

(29)

Satu prosedur monitor dapat diimplementasikan

menggunakan semaphore untuk melindungi entri-nya.

Contoh monitor dengan Java :

(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.

(31)

Rutin dapat berbentuk sebagai berikut :

(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 {

(33)

Konstruksi

forall

Untuk memulai proses sejenis yang serupa secara bersama-sama :

Forall (I=0; I < n; I++) {

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

.

(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.

(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 :

(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;

(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.

(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.

(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.

(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];

(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;

(42)

Gambar 8.10 Lokasi Memori Bersama untuk contoh program UNIX

(43)

#include <sys/types.h>

#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);

}

(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);

}

(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);

(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 */

(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) {

struct sembuf sembuffer, *sops; sops = &sembuffer;

sops->sem_num = 0; sops->sem_op = 1; sops->sem_flg = 0;

if (semop(*s, sops, 1) <0) {

(48)

SAMPLE OUTPUT

process pid = 0, partial sum = 250000

process pid = 26127, partial sum = 250500 The sum of 1 to 1000 is 500500

(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); }

(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();

(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); }

}

Gambar

Gambar 8.1      Shared Memory Multiprocessor
TABEL 8.1 Beberapa Bahasa Pemrograman Paralel
Gambar 8.2 Konstruksi FORK-JOIN
Gambar 8.4 pthread_create() and pthread_join().
+7

Referensi

Dokumen terkait

Kesimpulan dari penelitian ini adalah pengaruh interaksi ruang simpan refrigerator pada wadah plastik selama 12 minggu berpengaruh sangat nyata terhadap parameter yang diamati

Fasilitas dan kemudahan dalam mengurus izin bukanlah aspek yang terlalu dibutuhkan oleh investor tetapi yang terpenting yaitu perlindungan hukum

Selama mengikuti kegiatan magang ini penulis ditempatkan pada Sub Bagian Keuangan dan Program dimana bagian tersebut sesuai dengan judul laporan magang penulis yaitu Proses

Terkait dengan masalah yang diteliti, maka data primer diperoleh dari informasi yang diberikan oleh Kepala Sekolah SDN Bandar Dua dan Madrasah Ibtidaiyah al-Ihsan serta

“Salah satu tujuan mengapa dicanangkannya program ‘Bela Beli Kulon Progo’ ini adalah untuk pengentasan kemiskinan di Kabupaten Kulon Progo. Pemerintah berupaya untuk

unsur lembaga litbang, perguruan tinggi, dan industri.  Keanggotaan konsorsium riset paling tidak terdiri atas satu lembaga riset, satu perguruan tinggi dan satu

Metode penelitian yang digunakan adalah metode penelitian kulaitatif subjek penelitian berjumlah 7 orang, yaitu mahasiswa yang sudah menikah pada jurusan PAI FITK

Ledy Daiyana (2019) menulis skripsi yang berjudul “Tindak Tutur Ilokusi Sopir Truk di Rumah Makan yang Ada di Kecamatan Pulau Punjung, Kabupaten Dharmasraya”.