PIPELINE 8.1.1 PERANAN MEMORI CACHE Tiap stage dalam pipeline diharapkan menyelesaikan operasinya dalam satu clock cycle. Karenanya, periode clock harus cukup lama untuk menyelesaikan tugas yang sedang dilakukan pada tiap stage. Jika unit yang berbeda memerlukan jumlah waktu yang berbeda, maka periode clock harus memungkinkan tugas terlama dapat diselesaikan. Suatu unit yang menyelesaikan tugasnya lebih awal akan idle selama sisa periode clock. Karenanya, pipelining paling efektif dalam meningkatkan performa jika tugas yang sedang dilakukan dalam stage yang berbeda memerlukan jumlah waktu yang sama. Pertimbangan ini terutama penting untuk langkah pengambilan instruksi (instruct:c'! fetch), yang menetapkan sate periode clock pada Gambar 8.2a. Clock cycle harus setara a.= lebih besar daripada waktu yang diperlukan untuk menyelesaikan operasi pengambilan. Ah.:-., tetapi, waktu akses memori utama mungkin sepuluh kali lebih besar daripada waktu yang diptlukan untuk menjalankan operasi pipeline stage dasar dalam prosesor, misalnya penambar2m dua bilangan. Jadi, jika tiap pengambilan instruksi memerlukan akses ke memori utama, rr.a."a pipelining tidak akan begitu berguna. Penggunaan memori cache menyelesaikan persoalan akses memori. Secara khusus, p :: saat cache disertakan pada chip yang sama dengan prosesor, maka waktu akses ke cache bias ya sama dengan waktu yang diperlukan untuk menjalankan operasi dasar lain di dalam pro:. sor. Hal ini memungkinkan membagi pengambilan dan pengolahan instruksi ke dalam langk langkah dengan durasi yang lebih kurang setara. Tiap langkah dilakukan dengan pipeline s:.=..~ yang berbeda, dan periode clock dipilih untuk disesuaikan dengan yang paling panjang. 8.1.2 PERFORMA PIPELINE Prosesor pipelined pada Gambar 8.2 menyelesaikan pengolahan satu instruksi pada tiap c:, cycle, yang berarti kecepatan pengolahan instruksi tersebut empat kali lebih besar dari op e. berurutan. Peningkatan potensial dalam performa yang dihasilkan dari pipelining proporj,_M dengan jumlah pipeline stage. Akan tetapi, peningkatan ini hanya akan dicapai jika ope pipelined seperti yang digambarkan pada Gambar 8.2a dapat dipertahankan tanpa inter melalui eksekusi program. Sayangnya,
ini bukanlah masalahnya. Untuk berbagai alasan, salah satu pipeline stage mungkin tidak dapat menyelesaikan pengolahan instruksinya dalam waktu yang ditentukan. Misalnya, stage E dalam four-~ pipeline pada Gambar 8.2b bertanggung jawab untuk operasi aritmatika dan logika, dan clock cycle ditetapkan untuk tugas ini. Sekalipun ini mungkin cukup untuk sebagian besar rasi, beberapa operasi, misalnya pembagian, mungkin memerlukan waktu penyelesaian lebih banyak. Gambar 8.3 menunjukkan contoh dimana penyelesaian operasi yang ditendalam instruksi IZ memerlukan tiga cycle, dari cycle 4 hingga cycle 6. Jadi, pada cycle 6, Write stage tidak boleh melakukan apapun, karena tidak memiliki data untuk dikes Sementara itu, informasi dalam buffer B, harus tetap lengkap hingga Execute stage telah M lesaiakan operasinya. Ini berarti stage 2 dan, selanjutnya, stage 1 diblok agar tidak men instruksi baru karena informasi dalam B , tidak dapat di-overwrite. Jadi, langkah D4 dan F; ditunda seperti yang ditunjukkan. Operasi pipelined pada Gambar 8.3 dikatakan stalled selama dua clock cycle. pipelined normal dimulai lagi pada cycle 7. Tiap kondisi yang menyebabkan pipeline stall but hazard. Kita baru saja memperhatikan contoh data hazard. Data hazard adalah tiap k dimana source atau destination operand suatu instruksi tidak tersedia pada waktu diperl dalam pipeline. Akibatnya beberapa operasi harus di tunda dan pipeline mengalami stab. Pipeline juga dapat di-stall karena jeda dalam ketersediaan instruksi. Misalnya, hal ini dapat merupakan akibat dari suatu miss dalam cache, yang meminta instruksi diambil dari memori utama. Hazard tersebut sering disebut control hazard atau instruction hazard. Efek cache miss pada operasi pipelined diilustrasikan pada Gambar 8.4. Instruksi II diambil dari cache pada cycle 1, dan eksekusinya berjalan secara normal. Akan tetapi, operasi fetch untuk instruksi 129 yang dimulai pada cycle 2, menghasilkan cache miss. Unit pengambilan instruksi sekarang harus menangguhkan tiap request pengambilan berikutnya dan menunggu IZ tiba. Kita
8.4b. Gambar ini menunjukkan fungsi yang dijalankan oleh tiap pipeline stage dalam tiap clock cycle. Perhatikanlah bahwa unit Decode idle pada cycle 3 hingga 5, unit Execute idle pada cycle 4 hingga 6, dan unit Write idle pada cycle 5 hingga 7. Periode idle tersebut disebut stall. Sering disebut juga sebagai bubble dalam pipeline. Setelah terbentuk akibat jeda pada salah satu pipeline stage, maka bubble bergerak menurun hingga mencapai unit terakhir. Tipe hazard ketiga yang mungkin ditemui dalam operasi pipelined dikenal sebagai structural hazard. Ini adalah situasi pada saat dua instruksi
perlu menggunakan resource hardware tertentu pada waktu yang sama. Kasus paling umum dimana hazard ini muncul adalah pada akses ke memori. Satu instruksi mungkin perlu mengakses memori sebagai bagian dari Execute atau Write stage pada saat instruksi lain sedang diambil. Jika instruksi dan data berada pada unit cache yang sama, maka hanya satu instruksi yang dapat dilakukan dan instruksi lain ditunda. Banyak prosesor menggunakan cache instruksi dan data terpisah untuk menghindari jeda ini. Contoh structural hazard ditunjukkan pada Gambar 8.5. Gambar ini menunjukkan bagaimana instruksi load Load X(R1),R2 dapat diakomodasi dalam contoh 4-stage pipeline kita. Alamat memori, X+ [R1], dihitun pada langkah EZ pada cycle 4, kemudian akses memoriberlangsung pada cycle S. OpeYandyan dibaca dari memori dituliskan ke dalam register R2 pada cycle 6. Ini berarti langkah ekseku~: instruksi ini memerlukan dua clock cycle (cycle 4 dan 5). Hal ini menyebabkan pipeline star= selama satu cycle, karena instruksi IZ dan 1 3 memerlukan akses ke register file pada cycle 6 Sekalipun instruksi dan datanya tersedia, pipeline distall karena satu resource hardware, yai%w register file, tidak dapat menangani dua operasi sekaligus. Jika register file memiliki dua poinput, yaitu, j ika memungkinkan dua operasi tulis simultan, maka pipeline tidak akan di-star Secara umum, structural hazard dicegah dengan menyediakan resource hardware yang cukldalam chip prosesor.
Sangat penting untuk memahami bahwa pipelining tidak menyebabkan instruksi indiv.,aa. dieksekusi lebih cepat; sebaliknya, pipelining meningkatkan throughput, dimana through: diukur dari kecepatan penyelesaian eksekusi instruksi. Setiap kali salah satu dari stage pipeline tidak dapat menyelesaikan operasinya dalam satu clock cycle, maka pipeline stall. terjadi beberapa degradasi dalam performa. Jadi, level performa penyelesaian satu ins pada tiap clock cycle sebenarnya adalah Batas atas untuk throughput yang dapat dicapai da:. prosesor pipelined yang diatur seperti pada Gambar 8.2b. Tujuan penting dalam mendesain prosesor adalah untuk mengidentifikasi semua h yang dapat menyebabkan pipeline stall dan menmukan cara meminimalisasi pengaruhn;.B. Pada bagian selanjutnya kita membahas berbagai hazard, mulai dari data hazard, dilanju•~dengan control hazard. Pada tiap kasus kits menampilkan beberapa teknik yang digunakan
untuk mengurangi pengaruh negatifnya pada performa. Kita kembali ke persoalan penilaian performa pada Bagian 8.8. 8.2 DATA HAZARD Data hazard adalah situasi dimana pipeline di-stall karena data yang akan dikenai operasi ditunda dengan beberapa alasan, seperti yang diilustrasikan pada Gambar 8.3. Kita sekarang akan menganalisa persoalan ketersediaan data dalam beberapa detil. Perhatikan suatu program yang berisi dua instruksi, I, diikuti oleh I2. Pada saat program ini dieksekusi dalam pipeline, eksekusi IZ dapat mulai sebelum eksekusi I, diselesaikan. Hal ini berarti hasil I, mungkin tidak tersedia untuk digunakan oleh I2. Kita harus memastikan bahwa hasil yang diperoleh pada saat istruksi dieksekusi dalam prosesor pipelined identik dengan yang diperoleh pada saat instruksi yang sama dieksekusi secara berurutan. Potensi mendapatkan hasil yang tidak tepat pada saat operasi dilakukan secara konkuren dapat ditunjukkan dengan contoh sederhana berikut. Asumsikan A =5, dan perhatikan dua operasi berikut: AF--3+A BF-4xA Pada saat operasi tersebut dilakukan dalam urutan tersebut, maka hasilnya adalah B=32. Tetapi keduanya dilakukan secara konkuren, nilai A yang digunakan dalam menghitung B adalah nilai awal, 5, sehingga memberikan hasil yang tidak tepat. Jika dua operasi ini dilakukan oleh instruksi dalam suatu program, maka instruksi tersebut harus dieksekusi satu demi satu, karena data yang digunakan pada instruksi kedua tergantung pada hasil instruksi pertama. Sebaliknya, dua operasi Ate- 5 x C B<- 20 + C dapat dilakukan secara konkuren, karena operasi tersebut Baling bebas. Time Clock cycle 1
2
3
4
5
6
7
8
9
Instruksi 11 (Mul) 12 (Add)
1
3 14 Gambar 8.6 = ~c-eilne di-stall oleh :ata dependency irara D2 dan W1.
Contoh ini mengilustrasikan batasan dasar yang: harus dilakukan untuk menjamin hasil yang tepat. Pada saat dua operasi saling tergantung satu sama lain, maka keduanya harus dilakukan secara berurutan dalam urutan yang benar. Kondisi ini jelas memiliki konsekuensi yang mendalam. Memahami implikasinya adalah kunci untuk memahami berbagai alternatif desain dan pertukaran yang dihadapi dalam komputer pipelined. Perhatikan pipeline pada Gambar 8.2. Data dependency yang barn saja dideskripsikan muncul pada saat destinasi satu instruksi digunakan sebagai source pada instruksi berikutnya. Misalnya, dua instruksi Mul R2,R3,R4 Add R5,R4,R6 menghasilkan data dependency. Hasil dari instruksi perkalian ditempatkan dalam register R4, yang kemudian merupakan salah satu dari dua source operand pada instruksi Add. Dengan mengasumsikan bahwa operasi perkalian memerlukan satu clock cycle untuk selesai, maka eksekusi akan dilakukan seperti yang ditunjukkan pada Gambar 8.6. Pada scat unit Decode men-decode instruksi Add pada cycle 3, unit tersebut mengetahui bahwa R4 digunakan sebagai source operand. Karenanya, langkah D pada instruksi tersebut tidak dapat diselesaikan hingga langkah W pada instruksi multiply telah diselesaikan. Penyelesaian langkah DZ harus ditunda hingga clock cycle 5, dan ditunjukkan sebagai langkah D2A pada gambar tersebut. Instruksi 13 diambil pada cycle 3, tetapi decoding-nya harus ditunda karena langkah D3 tidak dapat mendahului DZ. Karenanya, eksekusi pipelined di-stall selama dua cycle. 8.2.1 OPERAND FORWARDING Data hazard yang baru saja dideskripsikan muncul karena satu instruksi, instruksi IZ pada Gambar 8.6, menunggu data dituliskan dalam register file. Akan tetapi, data tersebut tersedia pada output ALU pada saat Execute stage menyelesaikan langkah E,. Karenanya, jeda dapat dikurangi, atau mungkin dihilangkan, jika kita mengatur agar basil instruksi Il di-forward langsung untuk digunakan pada langkah E2.
ter file. Pengaturan ini mirip dengan struktur tiga-bus pada Gambar 7.8, kecuali bahwa telah ditambahkan register SRC1, SRC2, dan RSLT. Register tersebut merupakan interstage buffer yang diperlukan untuk operasi pipelined, seperti yang diilustrasikan pada Gambar 8.7b. Dengan mengacu ke Gambar 8.2b, register SRC 1 dan SRC2 adalah bagian dari buffer B2 dan RSLT adalah bagian B3. Mekanisme data forwarding disediakan oleh jalur koneksi berwarna biru. Dua multiplexer yang dihubungkan pada input ke ALU memungkinkan data pada bus destinasi lebih dipilih daripada isi register SRC 1 atau SRC2. Pada saat instruksi pada Gambar 8.6 dieksekusi dalam datapath pada Gambar 8.7, maka operasi yang dilakukan pada tiap clock cycle adalah sebagai berikut. Setelah decoding instruksi IZ dan mendeteksi data dependency, maka dibuat suatu keputusan untuk menggunakan data forwarding. Operand tidak terlibat dalam dependency tersebut, register R2, dibaca dan di-load ke dalam register SRC 1 pada clock cycle 3. Pada clock cycle berikutnya, hash dari instruksi II tersedia dalam register RSLT, dan karena koneksi forwarding, maka hash tersebut dapat digunakan pada langkah E2. Karenanya, eksekusi IZ dilakukan tanpa interupsi. 8.2.2 MENANGANI DATA HAZARD DALAM SOFTWARE Pada Gambar 8.6, kita mengasumsikan data dependency ditemukan oleh hardware pada scat instruksi di-decode. Hardware kontrol menunda pembacaan register R4 hingga cycle 5, sehingga memunculkan 2-cycle stall kecuali jika digunakan operand forwarding. Suatu pendekatan alternatif adalah dengan menyerahkan tugas pendeteksian data dependency dan penanganannya pada software. Dalam hal ini, compiler dapat menyatakan jeda dua-cycle yang diperlukan antara instruksi I, dan IZ dengan menyesipkan instruksi NOP (No-operation) , sebagai berikut: ii: Mu 1 R2, R3, R4 NOP NOP 1 2: Add R5, R4, R6 Jika tanggung jawab untuk mendeteksi dependency tersebut sepenuhnya diserahkan pada software, maka kompiler harus menyisipkan instruksi NOP untuk mendapatkan hash yang tepat. Kemungkinan ini mengilustrasikan link tertutp antara kompiler dan hardware. Suatu fitur khusus dapat diimplementasikan dalam hardware atau diserahkan pada
kompiler. Penyerahan tugas seperti penyisipan instruksi NOP ke kompiler menghasilkan hardware yang lebih sederhana. Dengan menyadari kebutuhan terhadap jeda, maka kompiler dapat mencoba menyusun ulang instruksi untuk melakukan tugas yang berguna dalam slot NOP, dan dengan demikian mencapai performa yang lebih baik. Sebaliknya, penyisipan instruksi NOP menghasilkan ukuran kode yang lebih besar. Juga, sering terjadi arsitektur suatu prosesor memiliki beberapa implementasi hardware, yang menawarkan fitur berbeda. Instruksi NOP yang disisipkan untuk memenuhi persyaratan satu implementasi mungkin tidak diperlukan dan, karenanya, akan menggurangi performa implementasi yang berbeda. x.2.3 EFEK SAMPING Data dependency yang ada pada contoh sebelumnya eksplisit dan mudah dideteksi karena register yang terlibat dinamai sebagai destinasi dalam instruksi I, dan source dalam IZ. Kadangkadang suatu instruksi mengubah isi register selain yang disebut sebagai destinasi. contohnya adalah instruksi yang menggunakan mode pengalamatan autoincrement atau autodecrement. Selain untuk menyimpan data barn dalam lokasi destinasinya, instruksi tersebut mengubah isi source register yang digunakan untuk mengakses salah satu operandnya. Semua tindakan pencegahan untuk menangani data dependency yang melibatkan lokasi destinasi harus juga diterapkan pada register yang dipengaruhi oleh operasi autoincrement atau autodecrement. Pada saat lokasi selain yang secara eksplisit disebut dalam satu instruksi sebagai operand destinasi dipengaruhi, maka instruksi tersebut dikatakan memiliki efek samping (side effect). Misalnya, instruksi stack, seperti push dan pop, menghasilkan efek samping yang serupa karena instruksi tersebut secara implisit menggunakan mode pengalamatan autoincrement dan autodecrement. Efek samping lain yang melibatkan condition code flag, adalah yang digunakan oleh instruksi seperti conditional branch dan add-with-carry. Misalkan register R1 dan R2 menyimpan bilangan integer double-precision yang akan kita tambahkan ke bilangan double-precision yang lain dalam register R3 dan R4. Hal ini dapat dicapai sebagai berikut: Add R1, R3 AddWithCarry R2,R4 Dependency implisit ada diantara dua instruksi ini melalui carry flag. Flag ini diset oleh instruksi pertama dan digunakan pada instruksi kedua, yang menjalankan operasi
R4 F-- [R2] + [R4] + carry Instruksi yang memiliki efek samping meningkatkan banyaknya data dependency, yang menghasilkan peningkatan substantial kompleksitas hardware atau software yang diperlukan untuk menyelesaikannya. Untuk alasan ini, desain instruksi untuk eksekusi pada pipelined hardware sebaiknya memiliki beberapa efek samping. Idealnya, hanya isi lokasi destinasi, lokasi register atau memori, yang dipengaruhi oleh tiap instruksi. Efek samping, seperti setting condition code flag atau updating isi address pointer, dijaga pada minimum. Akan tetapi, Bab 2 menunjukkan bahwa mode pengalamatan autoincrement dan autodecrement secara potensial berguna. Condition code flag juga diperlukan untuk mencatat informasi penghasil carry atau penyebab overflow dalam operasi aritmatika. Pada Bagian 8.4 kita menunjukkan bagaimana fungsi tersebut dapat disediakan oleh sarana lain yang konsisten dengan organisasi pipelined dan dengan persyaratan optimizing compiler. 8.3 INSTRUCTION HAZARD Tujuan unit pengambilan instruksi fetch adalah untuk menyediakan arus instruksi tetap bagi unit eksekusi. Kapanpun arus ini diinterupsi, maka pipeline stall, seperti pada Gambar 8.4 yang mengilustrasikan kasus cache miss. Instruksi branch dapat pula menyebabkan pipeline menjadi stall. Sekarang kita akan menganalisa efek instruksi branch dan teknik yang dapat digunakan untuk mengurangi pengaruhnya. Kita mulai dengan unconditional branch. 8.3.1 UNCONDITIONAL BRANCH Gambar 8.8 menunjukkan rangkaian instruksi yang dieksekusi dalam two-stage pipeline. Instruksi 11 hingga 1 3 disimpan pada alamat memori yang berurutan, dan IZ adalah instruks: branch. Misalkan branch target adalah instruksi IV Pada clock cycle 3, operasi pengambilan untuk instruksi 1 3 berjalan pada scat yang sama dengan instruksi branch yang sedang di-decode dan alamat target yang dihitung. Pada clock cycle 4, prosesor harus membuang I3, yang telah diambil secara tidak tepat, dan mengambil instruksi Ik. Sementara itu, unit hardware yang bertanggung jawab untuk langkah Execute (E) harus diberitahu untuk tidak melakukan apapun selama periode clock tersebut. Jadi, pipeline di-stall selama satu clock cycle. Waktu yang hilang karena instruksi branch sering disebut branch penalty. Pada Gamb~:: 8.8, branch penalty adalah satu clock cycle. Untuk pipeline yang lebih panjang, branch penal-µ bisa lebih tinggi. Misalnya, Gambar 8.9a menunjukkan efek instruksi branch pada four-staff. pipeline. Kita telah mengasumsikan bahwa alamat branch dihitung pada langkah E2. Instrul I3 dan 1 4 harus
dibuang, dan instruksi target, Ik , diambil pada clock cycle 5. Jadi, branch penal-_% adalah dua clock cycle. Pengurangan branch penalty dilakukan dengan menghitung alamat branch lebih awal dalam pipeline. Biasanya, unit pengambilan instruksi memiliki dedicated hardware untuk mengide tifikasi instruksi branch dan menghitung alamat branch target secepat mungkin setelah siu:'-M instruksi diambil. Dengan hardware tambahan ini, kedua tugas tersebut dapat dilakukan p langkah D2, menghasilkan rangkaian kejadian yang ditunjukkan pada Gambar 8.9b. Dalam ini, branch penalty hanya satu clock cycle. Queue dan Prefetching Instruksi Cache miss atau instruksi branch men-stall pipeline selama satu clock cycle atau lebih. Untuk mengurangi efek interupsi tersebut, banyak prosesor menggunakan unit pengambilan yang canggih yang dapat mengambil instruksi sebelum diperlukan dan meletakkannya dalam queue. Biasanya, queue instruksi dapat menyimpan beberapa instruksi. Suatu unit terpisah, yang kite sebut unit dispatch, mengambil instruksi dari bagian depan queue den mengirimkannya ke un'eksekusi. Hal ini menghasilkan organisasi seperti yang ditunjukkan pada Gambar 8.10. ULdispatch juga melakukan fungsi decoding. Agar efektif, unit pengambilan harus memiliki kemampuan decoding den pengola yang cukup untuk mengenali dan mengeksekusi instruksi branch. Unit tersebut menjaga qL:je instruksi tetap terisi sepanjang waktu untuk mengurangi pengaruh jeda occasional pada mengambil instruksi. Pada seat pipeline stall karena data hazard, misalnya, unit dispatch ~: dapat mengeluarkan instruksi dari queue instruksi. Akan tetapi, unit pengambilan terus rt-:: ambil instruksi den menambahkannya ke queue. Sebaliknya, jika terdapat jeda dalam pen_= bilan instruksi karena branch atau cache miss, make unit dispatch terus mengeluarkan instr dari queue instruksi. Gambar 8.11 mengilustrasikan bagaimana panjang queue berubah den bagaimana pe-_ ruhnya terhadap hubungan antara pipeline stage yang berbeda. Kite telah mengasurn;bahwa queue pada awalnya berisi satu instruksi. Setiap operasi pengambilan menam - satu instruksi ke queue den setiap operasi dispatch mengurangi panjang queue sebesar Karenanya, panjang queue tetap same dalam empat clock cycle pertama. (Terdapat lar-_ F den D dalam tiap cycle tersebut.) Misalkan instruksi I, memunculkan 2cycle stall. h.i.a tersedia ruang dalam queue tersebut, make unit pengambilan terus mengambil instruk-s.: panjang queue meningkat menjadi 3 pada clock cycle 6. Instruksi IS adalah instruksi branch. Instruksi targetnya, I k , diambil pada cycle 7. ,;a struksi 1 6 dibuang. Instruksi branch biasanya akan menyebabkan stall pada cycle 7 akiba: __ buangan instruksi I6. Sebaliknya,
instruksi 1 4 di-dispatch dari queue ke decoding stage. ~!-_ discarding I6, panjang queue menurun hingga 1 pada cycle 8. Panjang queue akan berad.: nilai ini hingga menemui stall lain. Sekarang amati rangkaian penyelesaian instruksi pada Gambar 8.11. Instruksi I.. . I.. ;* den Ik menyelesaikan eksekusi dalam dock cycle yang berurutan. Karenanya, instruksi ~ _ tidak meningkatkan waktu eksekusi secara keseluruhan. Hal ini karena unit pengmab.:.=struksi mengeksekusi instruksi branch (dengan menghitung alamat branch) secara kodengan eksekusi instruksi lain. Teknik ini disebut sebagai branch folding.
Perhatikanlah branch folding hanya terjadi jika pada saat memasuki instruksi branch, setidaknya tersedia satu instruksi dalam queue selain instruksi branch. Jika hanya instruksi branch yang terdapat dalam queue, maka eksekusi akan dilakukan seperti pada Gambar 8.9b. Oleh karena itu, diinginkan untuk mengatur queue agar selalau penuh sepanjang waktu, untuk menjamin suplai instruksi yang cukup untuk pengolahan. Hal ini dapat dicapai dengan meningkatkan kecepatan unit pengambilan membaca instruksi dari cache. Pada banyak prosesor, lebar koneksi antara unit pengambilan dan cache instruksi memungkinkan pembacaan lebih dari satu instruksi pada tiap clock cycle. Jika unit pengambilan mengisi queue instruksi segera setelah terjaadi branch, maka probabilitas terjadinya branch folding akan meningkat. Adanya queue instruksi juga bermanfaat dalam menangani cache miss. Pada saat terjadi cache miss, unit dispatch terus mengirim instruksi untuk eksekusi sepanjang queue instruksi tidak kosong. Sementara itu, blok cache yang dimaksud dibaca dari memori utama atau dari cache sekunder. Pada scat operasi pengambilan dilanjutkan, queue instruksi diisi ulang. Jika queue tidak kosong, maka cache miss tidak akan berpengaruh pada kecepatan eksekusi instruksi. Secara ringkas, queue instruksi mengurangi pengaruh instruksi branch pada performa melalui prows branch folding. Dan juga memiliki efek yang sama pada stall yang disebabkan oleh cache miss. Keefektifan teknik ini ditingkatkan pada saat unit pengambilan instruksi dapat membaca lebih dari satu instruksi pada satu waktu dari cache instruksi. 13.2 CONDITIONAL BRANCH DAN BRANCH PREDICTION Instruksi conditional branch menimbulkan hazard tambahan yang disebabkan oleh ketergantungan kondisi branch pada hash instruksi sebelumnya. Keputusan untuk branch tidak dapat dibuat hingga eksekusi instruksi tersebut telah selesai.
Instruksi branch sering terjadi. Sebenarnya, instruksi tersebut menggambarkan sekitar 20 persen count instruksi dinamik pada kebanyakan program. (Count dinamik adalah jumlah eksekusi instruksi, yang memperhitungkan fakta bahwa beberapa instruksi program dieksekusi berulang kali karena loop.) Karena branch penalty, persentase yang besar ini akan mengurangi perolehan performa yang diharapkan dari pipelining. Untungnya, instruksi branch dapat ditangani dengan beberapa cara untuk mengurangi pengaruh negatifnya pada kecepatan eksekusi instruksi. Delayed Branch Pada Gambar 8.8, prosesor mengambil instruksi 1 3 sebelum menentukan apakah instruksi tersebut, 12, adalah instruksi branch. Pada scat eksekusi IZ diselesaikan dan dibuat suatu branch, maka prosesor harus membuang I3 dan mengambil instruksi pada branch target. Lokasi setelah instruksi branch disebut branch delay slot. Mungkin terdapat lebih dari satu branch delay slot, tergantung pada waktu yang diperlukan untuk mengeksekusi instruksi branch. Misalnya, terdapat dua branch delay slot pada Gambar 8.9a dan satu delay slot pada Gambar 8.9b. Instruksi pada delay slot selalu diambil dan setidaknya telah dieksekusi sebagian sebelum keputusan branch dibuat dan alamat target branch dihitung. Suatu teknik yang disebut delayed branching dapat meminimalisasi penalty yang terjadi sebagai akibat instruksi conditional branch. Ide tersebut sederhana. Instruksi dalam delay slot selalu diambil. Oleh karena itu, kita akan mengaturnya agar dieksekusi sepenuhnya baik dilakukan branch atau tidak. Tujuannya adalah untuk dapat menempatkan instruksi yang berguna dalam slot tersebut. Jika tidak ada instruksi berguna yang bisa ditempatkan dalam delay slot, maka slot ini harus diisi dengan instruksi NOP Situasi ini tepat sama dengan kasus data dependency yang dibahas pada Bagian 8.2. Perhatikan rangkaian instruksi yang dinyatakan pada Gambar 8.12a. Register R2 digunakan sebagai counter untuk menentukan berapa kali isi register R1 digeser ke kiri. Untuk prosesor dengan satu delay slot, instruksi tersebut dapat disusun ulang seperti yang ditunjukkan pada Gambar 8.12b. Instruksi shift diambil pada saat instruksi branch dieksekusi. Setelah mengevaluasi branch condition, prosesor mengambil instruksi pada LOOP atau pada NEXT, tergantung pada apakah masing-masing branch condition benar atau salah. Pada kasus lain, prosesor menyelesaikan eksekusi instruksi shift. Rangkaian kejadian selama dua lewatan terakhir dalam loop diilustrasikan pada Gambar 8.13. Operasi pipelined tidak diinterupsi kapanpun, dan tidak ada idle cycle. Secara logika, program tersebut dieksekusi seakan instruksi branch berada setelah instruksi shift. Branching terjadi satu instruksi lebih awal daripada yang ditampilkan dalam rangkaian instruksi dalam memori, sehingga bernama "delayed branch." (a) Loop program awal LOO
Decremen R2 Branch=O LO
R1 Shift left R NEX Add l (b) Instruksi yang disusun ulang
Keefektifan pendekatan delayed branch tergantung pada seberapa Bering pengaturan ulang instruksi dimungkinkan seperti dalam Gambar 8.12. Data eksperimen yang dikumpulkan dari banyak program mengindikasikan bahwa teknik kompilasi yang rumit dapat menggunakan satu branch delay slot pada maksimal 85 persen kasus. Untuk prosesor dengan dua branch delay slot, kompiler mencoba menemukan dua instruksi sebelum instruksi branch yang dapat dipindahkannya ke delay slot tanpa menimbulkan error logika. Kesempatan untuk menemukan dua instruksi semacam itu lebih sedikit dari kemungkinan untuk menemukan satu. Jadi, jika peningkatan jumlah pipeline stage melibatkan peningkatan jumlah branch delay slot, maka peningkatan potensial dalam performa tidak akan sepenuhnya tampak. Prediksi Branch Teknik lain untuk mengurangi branch penalty yang berhubungan dengan conditional branch adalah dengan mencoba memprediksikan apakah suatu branch akan dilakukan atau tidak. Bentuk paling sederhana dari prediksi branch adalah dengan mengasumsikan bahwa branch tersebut tidak akan terjadi dan terus mengambil instruksi dengan susunan alamat yang berurutan. Hingga branch condition dievaluasi, eksekusi instruksi disepanjang jalur yang diprediksikan harus dilakukan pada basis spekulatif. Eksekusi speculatif berarti instruksi tersebut dieksekusi sebelum prosesor yakin bahwa dia berada dalam rangkaian eksekusi yang tepat. Karenanya, harus diperhatikan bahwa tidak ada register prosesor atau lokais memori yang di-update hingga ada konfirmasi bahwa instruksi tersebut sebaiknya dieksekusi. Jika keputusan branch mengindikasikan sebaliknya, instruksi tersebut dan semua data yang berhubungan dengannya dalam unit eksekusi harus disingkirkan, dan instruksi yang tepat diambil dan dieksekusi.
Branch terprediksi yang tidak tepat diilustrasikan pada Gambar 8.14 untuk four-stag: pipeline. Gambar tersebut menunjukkan instruksi Compare diikuti oleh instruksi Branch: Prediksi branch terjadi di cycle 3, pada saat instruksi 1 3 sedang diambil. Unit pengambila:~ memprediksikan bahwa branch tersebut tidak akan dilakukan, dan kemudian melanjutkan u--tuk mengambil instruksi 1 4 pada saat 13 memasuki Decode stage. Hasil dari operasi compare tersedia pada akhir cycle 3. Dengan mengasumsikan bahwa hasil tersebut diteruskan dengue segera ke unit pengambilan instruksi,
maka branch condition dievaluasi pada cycle 4. Pada ti-.~I ini, unit pengambilan instruksi mengetahui bahwa prediksi tersebut tidak tepat, dan dua ir:struksi dalam execution pipe disingkirkan. Instruksi barn, Ik , diambil dari alamat branch tang=_ pada clock cycle 5. Jika keluaran branch random, maka setengah branch akan dilakukan. Jadi pendekat.:sederhana dengan mengasumsikan bahwa branch tidak akan dilakukan akan menghemat -5: persen waktu yang dibuang untuk melakukan conditional branch. Akan tetapi, performa leltbaik dapat dicapai jika kita mengatur beberapa instruksi branch yang diprediksikan untuk ~_lakukan dan yang lain untuk tidak dilakukan, tergantung pada kelakuan program yang diharzkan. Misalnya, instruksi branch pada akhir loop menyebabkan branch ke awal loop untuk set: lewatan melalui loop kecuali yang terakhir. Karenanya, sangat menguntungkan untuk mengasumsikan bahwa branch akan dilakukan dan unit pengambilan instruksi mulai mengambil ---struksi pada alamat traget branch. Sebaliknya, untuk instruksi branch pada awal loop progra_-_. h lebih menguntungkan untuk mengasumsikan bahwa branch tidak akan dilakukan. Keputusan tentang cara mana yang digunakan untuk memprediksi hasil branch day dibuat pada hardware dengan mengamati apakah alamat target branch lebih rendah atau let", tinggi daripada alamat instruksi branch. Pendekatan yang lebih fleksibel adalah menggunak ;mkompiler untuk memutuskan apakah suatu instruksi branch sebaiknya diprediksi untuk dilak_ kan atau tidak. Instruksi branch pada beberapa prosesor, seperti SPARC, menyertakan bran., prediction bit, yang diset ke 0 atau 1 oleh kompiler untuk mengindikasikan kelakuan vdiharapkan. Unit pengambilan instruksi mameriksa bit ini untuk memprediksi apakah bran.-i tersebut akan dilakukan atau tidak. Dengan salah satu skema tersebut, keputusan prediksi branch selalu sama setiap kali sly instruksi dieksekusi. Tiap pendekatan yang memiliki karakteristik ini disebut prediksi brae statik (static branch prediction). Pendekatan lain dimana keputusan prediksi (prediction de: sion) dapat berubah tergantung pada sejarah eksekusinya disebut prediksi branch dinamik i namic branch prediction).
8.4 PENGARUH PADA SET INSTRUKSI
Kita telah melihat bahwa beberapa instruksi lebih sesuai untuk eksekusi pipelined daripa:* yang lain. Misalnya, efek samping instruksi dapat menyebabkan data dependency yang c: ; diinginkan. Dalam bagian ini, kita menganalisa hubungan antara fitur eksekusi pipelined I instruksi mesin. Kita membahas dua aspek utama instruksi mesin-mode pengalamatan condition code flag. 8.4.1 MODE PENGALAMATAN Mode pengalamatan sebaiknya menyediakan sarana untuk mengakses berbagai struktur data secara mudah dan efisien. Mode penggalamatan yang baik antara lain index, indirect, autoincrement, dan autodecrement. Banyak prosesor menyediakan berbagai kombinasi mode tersebut untuk meningkatkan fleksibilitas set instruksinya. Mode pengalamatan complex, misalnya yang melibatkan double indexing, sering sekali ditemui. Dalam memilih mode pengalamatan untuk diimplementasikan dalam prosesor pipelined, kita harus memperhatikan efek tiap mode pengalamatan pads aliran instruksi dalam pipeline. Dua pertimbangan penting yang berkaitan dengan hal ini adalah efek samping mode seperti autoincrement dan autodecrement dan tingkat dimana mode pengalamatan complex menyebabkan pipeline menjadi stall. Faktor penting lain adalah apakah suatu mode akan lebih dipilih oleh suatu kompiler. Untuk membandingkan berbagai pendekatan, kita mengasumsikan model sederhana untuk mengakses operand di dalam memori. Instruksi Load X(R1),R2 memerlukan lima cycle untuk menyelesaikan eksekusi, seperti yang diindikasikan pada Gambar 8.5. Akan tetapi, instruksi Load (R1),R2 dapat diatur untuk sesuai dengan four-stage pipeline karena tidak diperlukan perhitungan alamat. Akses ke memori dapat berlangsung pada stage E. Mode pengalamatan yang lebih kompleks mungkin memerlukan beberapa akses ke memori untuk mencapai operand yang dimaksud. Misalnya, instruksi Load (X(R1)),R2 mungkin dieksekusi seperti pada Gambar 8.16a, dengan mengasumsikan bahwa index offset, X, dinyatakan dalam word instruksi. Setelah menghitung alamat pada cycle 3, prosesor perlu mengakses memori dua kali-pertama untuk membaca lokasi X +[R1] pada clock cycle 4 dan kemudian untuk membaca lokasi [X +[R1]] pada cycle 5. Jika R2 adalah source operand pada instruksi berikutnya, maka instruksi tersebut akan di-stall selama tiga cycle, yang dapat direduksi hingga dua cycle dengan operand forwarding, seperti yang ditunjukkan.
Untuk menerapkan operasi Load yang sama hanya menggunakan mode pengalamatan sederhana memerlukan beberapa instruksi. Misalnya, pada komputer yang memungkinkan tiga alamat operand, kita dapat menggunakan Add #X, R1, R2 Load (R2),R2 Load (R2),R2 Instruksi Add menjalankankan operasi R2 +- X +[R1]. Dua instruksi Load tersebut mengambil alamat dan kemudian operand dari memori. Rangkaian instruksi ini memerlukan sejur -lah clock cycle yang tepat sama dengan aslinya, instruksi Load tunggal, seperti pada Gamy: 8.16b. Contoh ini mengindikasikan bahwa, dalam prosesor pipelined, mode pengalamatan kornpleks yang melibatkan beberapa akses ke memori tidak selalu menghasilkan eksekusi yaL= lebih cepat. Keuntungan utama mode tersebut adalah mengurangi jumlah instruksi yang dipz-lukan untuk melakukan togas tertentu dan dengan demikian mengurangi ruang program yazz diperlukan dalam memori utama. Kerugian utamanya adalah waktu eksekusinya yang laT-.t menyebabkan pipeline stall, sehingga mengurangi keefektifannya. Mode tersebut memerluk hardware yang lebih kompleks untuk men-decode dan mengeksekusinya. Juga, tidak cots untuk bekerja dengan kompiler. Set instruksi prosesor modern didesain untuk memanfaatkan semaksimal mungkin ha: ware pipelined. Karena mode pengalamatan kompleks tidak cocok untuk eksekusi pipelines aka harus dihindari. Mode pengalamatan yang digunakan dalam prosesor modern serg memiliki fitur berikut:
W
• Akses ke operand tidak memerlukan lebih dari satu akses ke memori. • Hanya instruksi load dan store yang mengakses memory operand. • Mode pengalamatan yang digunakan tidak memiliki efek samping. Tiga mode pengalamatan dasar yang memiliki fitur tersebut adalah register, register rect, dan index. Dua yang pertama tidak memerlukan perhitungan alamat. Pada mode i alamat tersebut dapat dihitung dalam satu cycle, baik nilai index dinyatakan dalam inset atau dalam register. Memori diakses pada cycle berikut. Tidak satupun dari mode ini mers,-'efek samping, dengan kemungkinan satu pengecualian. Beberapa arsitekstur, misalnya. memungkinkan alamat dihitung dalam mode index untuk dituliskan kembali ke index regz... Ini adalah efek samping yang tidak akan diijinkan sesuai petunjuk diatas. Perhatikanlah bahwa pengalamatan relative dapat
digunakan; ini adalah kasus khusus pengalamatan ind dimana program counter digunakan sebagai index register. Tiga fitur yang baru dirinci di atas pada awalnya dinyatakan sebagai bagian dari ko prosesor RISC. Arsitektur prosesor SPARC, yang sesuai dengan petunjuk tersebut, ditampi" pada Bagian 8.7.
8.6 OPERASI SUPERSKALAR Pipelining memungkinkan eksekusi instruksi secara konkuren. Beberapa instruksi terdapat dalam pipeline pada waktu yang sama, tetapi berada dalam stage eksekusi yang berbeda. Pada saat satu instruksi melakukan operasi ALU, instruksi lain di-decode dan yang lain lagi diambil dari memori. Instruksi memasuki pipeline dalam urutan program yang ketat. Tanpa hazard, satu instruksi memasuki pipeline dan satu instruksi menyelesaikan ekskeusi pada tiap clock cycle. Ini berarti throughput maksimum prosesor pipelined adalah satu instruksi per clock cycle. Pendekatan yang lebih agresif adalah dengan mernperlengkapi prosesor dengan banyak unit pengolahan untuk menangani beberapa instruksi secara paralel pada tiap stage pengolahan. Dengan pengaturan ini, beberapa instruksi memulai eksekusi pada clock cycle yang sama, dan prosesor disebut menggunakan multiple-issue. Prosesor tersebut mampu mencapai throughput eksekusi instruksi lebih dari satu instruksi per cycle. Dikenal sebagai prosesor superskalar. Banyak prosesor performa-tinggi menggunakan pendekatan ini. Kita memperkenalkan ide queue instruksi pada Bagian 8.3. Kita menekankan agar queue instruksi tetap terisi, maka prosesor harus dapat mengambil lebih dari satu instruksi pada satu waktu dari cache. Untuk operasi superskalar, pengaturan ini sangat penting. Operasi multipleissue memerlukan jalur yang lebih lebar ke cache dan unit multiple execution. Unit eksekusi terpisah disediakan untuk instruksi integer dan floating-point. Gambar 8.19 menunjukkan contoh prosesor dengan dua unit eksekusi, sate untuk integer dan satu untuk operasi floating-point. Unit Pengambilan instruksi mampu membaca dua instruksi pada satu waktu dan menyimpannya dalam queue instruksi. Pada tiap clock cycle, unit Dispatch mengambil dan me-decode sampai dengan dua instruksi dari bagian depan queue. Jika terdapat satu instruksi integer, satu instruksi floating-point, dan tidak ada hazard, maka kedua instruksi tersebut dikirim pada clock cycle yang sama.
Pada prosesor superskalar, efek yang merusak pada performa dari berbagai hazard menjadi semakin nyata. Kompiler dapat menghindari banyak hazard melalui pemilihan yang bijaksana dan penyusunan instruksi. Misalnya, untuk prosesor pada Gambar 8.19, kompiler harus berusaha untuk meng-interleave instruksi floating-point dan integer. Hal ini akan meng-enable unit dispatch untuk mempertahankan agar unit integer dan floating-point sibuk sepanjang waktu. Secara umum, performa tinggi dicapai jika kompiler dapat mengatur instruksi program untuk memanfaatkan secara maksimum unit hardware yang tersedia.
Pipeline timing ditunjukkan pada Gambar 8.20. 'Bayangan biru tersebut mengindik operasi dalam unit floating-point. Unit floatingpoint memerlukan tiga clock cycle untuk lesaikan operasi floatingpoint yang ditetapkan dalam II. Unit integer menyelesaikan eksei:.:: dalam satu clock cycle. Kita juga telah mengasumsikan bahwa unit floating-point diatur >e internal sebagai tiga-stage pipeline. Jadi, masih dapat menerima instruksi barn pada tiap eli cycle. Karenanya, instruksi 1 3 dan 14 memasuki unit dispatch pada cycle 3, dan keduanya dikirms pada cycle 4. Unit integer dapat menerima instruksi baru karena isntruksi Iz telah mend Write stage. Instruksi I, masih dalam fase eksekusi, tetapi telah pindah ke stage kedua p pipeline internal dalam unit floating-point. Oleh karena itu, instruksi 1 3 dapat memasuki std pertama. Dengan mengasumsikan tidak ada hazard yang ditemui, maka instruksi men}el:saikan eksekusi seperti yang ditunjukkan. 8.6.1 EKSEKUSI OUT-OF-ORDER Pada Gambar 8.20, instruksi dikirim pada urutan yang sama seperti dalam program. AkaL tetapi eksekusinya diselesaikan tidak sesuai dengan urutan tersebut. Apakah hal ini menimbulkan persoalan? Kita telah membahas persoalan yang muncul dari ketergantungan antar instruksi. Misalnya, jika instruksi IZ tergantung pada hasil dari Ip maka eksekusi IZ akan ditunda. Sepanjang ketergantungan tersebut ditangani dengan tepat, maka tidak ada alasan untuk menunda eksekusi suatu instruksi. Akan tetapi, komplikasi baru muncul pada saat kita mempertimbangkan kemungkinan suatu instruksi yang menyebabkan exception. Exception dapat disebabkan oleh error bus selama pengambilan operand atau operasi ilegal, misalnya usaha
membagi dengan nol. Hasil IZ ditulis kembali ke dalam register file pada cycle 4. Jika instruksi I, menyebabkan exception, maka eksekusi program berada dalam keadaan tidak konsisten (inconsistent state). Program counter menunjuk ke instruksi dimana terjadi exception. Akan tetapi, satu atau lebih
instruksi yang berurutan telah dieksekusi hingga selesai. Jika situasi tersebut diijinkan, maka prosesor disebut memiliki imprecise exception. Untuk menjamin keadaan konsisten (consistent state) pada saat terjadi exception, maka hash eksekusi instruksi harus dituliskan ke dalam lokasi destinasi sesuai dengan urutan program. Ini berarti kita harus menunda langkah W2 pada Gambar 8.20 hingga cycle 6. Selanjutnya, unit eksekusi integer harus menyimpan hash instruksi 129 dan karenanya tidak dapat menerima instruksi 1 4 hingga cycle 6, seperti pada Gambar 8.21a. Jika terjadi exception dalam suatu instruksi, maka semua instruksi berikutnya yang telah dieksekusi sebagian dibuang. Ini disebut precise exception.
Lebih mudah untuk menyediakan precise exception dalam hal interrupt eksternal. Pada saat interrupt eksternal diterima, unit Dispatch berhenti membaca instruksi baru dari queue instruksi, dan instruksi yang berada dalam queue dibuang. Semua prosesor yang eksekusinya ditunda dilanjutkan hingga selesai. Pada titik ini, prosesor tersebut dan semua registernya berada dalam keadaan konsisten, dan pengolahan interrupt dapat dimulai. 8.6.2 PENYELESAIAN EKSEKUSI Dengan menggunakan eksekusi out-of-order, unit eksekusi bebas untuk mengeksekusi instruksi lain dengan segera. Pada saat yang sama, instruksi harus diselesaikan sesuai dengan urutan program untuk memungkinkan precise exception. Persyaratan yang tampaknya bertentangan ini dapat diselesaikan jika eksekusi dapat dilakukan seperti pada Gambar 8.20, tetapi hasilnya ditulis ke register temporer. Isi register tersebut selanjutnya ditransfer ke register permanen dalam urutan program yang tepat. Pendekatan ini diilustrasikan pada Gambar 8.21b. Langkah TW adalah penulisan ke register temporer. Langkah W adalah langkah terakhir dimana isi register temporer ditransfer ke dalam register permanen yang sesuai. Langkah ini sering disebut langkah komitmen (commitment) karena efek instruksi tidak dapat dibalik setelah titik tersebut. Jika suatu instruksi menyebabkan exception, maka hasil tiap instruksi selanjutnya yang telah dieksekusi akan tetap berada dalam register temporer dan dapat dengan aman dibuang. Register temporer mengasumsikan peranan register permanen yang datanya disimpan dan diberi nama sama. Misalnya, jika register destinasi IZ adalah R5, maka register temporer yang digunakan dalam langkah TW2 diperlakukan sebagai R5 selama clock cycle 6 dan 7. Isinya akan di-forward ke tiap instruksi berikutnya yang mengacu ke R5 selama periode tersebut. Karena fitur ini, maka teknik ini disebut register renaming. Perhatikanlah bahwa register temporer hanya digunakan untuk
instruksi setelah IZ dalarn urutan program. Jika suatu instruksi yang mendahului Il perlu membaca R5 pada cycle 6 atau 7, maka instruksi tersebut akan mengakses register aktual R5, yang masih berisi data yang belum dimodifikasi oleh instruksi I2. Pada scat eksekusi out-of-order diijinkan, diperlukan suatu unit kontrol khusus untuk menjamin komitmen in-order. Ini disebut unit komitmen. Unit tersebut menggunakan queue yang disebut reorder buffer untuk menentukan instruksi mana yang sebaiknya ditetapkan berikutnya. Instruksi dimasukkan ke dalam queue sesuai dengan urutan program pada saat instruksi tersebut dikirim untuk eksekusi. Pada saat instruksi mencapai puncak queue dan eksekusi instruksi tersebut telah selesai maka basil yang tepat ditransfer dari register temporer ke register permanen dan instruksi tersebut dihapus dari queue. Semua resource yang ditetapkan untuk instruksi tersebut, termasuk register temporer, dibebaskan. Instruksi itu dinyatakan telah diberhentikan (retired) pada titik ini. Karena suatu instruksi hanya diberhentikan pada saat berada pada puncak queue, maka semua instruksi yang dikirim sebelumnya juga telah diberhentikan. Karenanya, instruksi dapat menyelesaikan eksekusi out of order, tetapi instruksi tersebut diberhentikan sesuai urutan program.