Arsitektur Komputer (Gunadarma) BAB 3

March 25, 2019 | Author: Ifan Faizal | Category: N/A
Share Embed Donate


Short Description

Terjemahan BAB 3 Arsitektur Komputer...

Description

BAB 3

Anas Sofyan Azhar SP Diokta redho lastin Ifan Faizal Adnan

Paralelisme Tingkat Instruksi: Konsep dan Tantangan

Semua prosesor sejak sekitar tahun 1985 menggunakan pipelining agar tumpang tindih dengan pelaksanaan instruksi dan peningkatan kinerja. Potensi tumpang tindih antara instruksi ini disebut instruction-level parallelism (ILP), karena instruksinya dapat dievaluasi secara paralel. Dalam bab ini serta Lampiran H, kita melihat sejauh mana tenknologi untuk memperluas pipelining dasar dengan meningkatkan jumlah  paralelisme yang dieksploitasi di antara instruksi. Bab ini berada pada tingkat yang jauh lebih maju daripada materi tentang  pipelining dasar pada Lampiran C. Jika Anda tidak t idak benar-benar memahami gagasan di Lampiran C, Anda harus meninjau kembali lampiran tersebut sebelum memasuki bab ini. Kita memulai bab ini dengan melihat keterbatasan yang dipaksakan oleh data dan pengendalian bahaya dan kemudian beralih ke topik untuk meningkatkan kemampuan kompiler dan prosesor untuk mengeksploitasi paralelisme. Bagian ini mengenalkan sejumlah besar konsep, yang kita bangun di bab ini dan bab berikutnya. Sementara beberapa bahan yang lebih mendasar dalam bab ini dapat dipahami tanpa adanya gagasan di dua bagian pertama, bahan dasar ini penting untuk bagian selanjutnya dari bab ini. Terdapat dua pendekatan yang dapat dipisahkan untuk dieksploitasi ILP: (1)  pendekatan yang mengandalkan perangkat keras untuk membantu menemukan dan mengeksploitasi paralelisme secara dinamis, dan (2) pendekatan yang bergantung pada teknologi perangkat lunak untuk menemukan paralelisme secara statis pada waktu kompilasi. Prosesor yang menggunakan dinamis, pendekatan berbasis hardware, termasuk seri Intel Core, mendominasi di pasar desktop dan server. Di pasar perangkat mobile pribadi, di mana efisiensi energi sering menjadi tujuan utama, perancang mengeksploitasi tingkat paralelisme tingkat instruksi yang lebih rendah. Jadi, pada

tahun 2011, sebagian besar prosesor untuk pasar PMD menggunakan pendekatan statis, seperti yang akan kita lihat di ARM Cortex-A8; Namun, prosesor masa depan (mis., ARM Cortex-A9 yang baru) menggunakan pendekatan dinamis. Pendekatan berbasis kompilator yang agresif telah dicoba berkali-kali dimulai pada tahun 1980an dan yang terbaru dalam seri Intel Itanium. Meskipun banyak usaha, pendekatan semacam itu  belum berhasil di luar jangkauan aplikasi ilmiah yang sempit. Dalam beberapa tahun terakhir, banyak teknik yang dikembangkan untuk satu  pendekatan telah dieksploitasi dalam desain yang terutama bergantung bergan tung pada yang lain. Bab ini memperkenalkan konsep dasar dan kedua pendekatan. Diskusi tentang keterbatasan pendekatan ILP termasuk di dalam bab ini, dan itu adalah keterbatasan yang secara langsung mengarah ke pergerakan untuk multicore. Memahami keterbatasan tetap penting dalam menyeimbangkan penggunaan ILP dan paralelisme tingkat thread. Pada bagian ini, kita membahas fitur dari kedua program dan prosesor yang membatasi jumlah paralelisme yang dapat dieksploitasi di antara instruksi, serta  pemetaan kritis antara struktur program dan struktur perangkat keras, yang merupakan kunci untuk memahami apakah properti program benar-benar akan membatasi Kinerja dan dalam keadaan apa.  Nilai CPI CPI (siklus per instruksi) untuk prosesor pipelined adalah jumlah CPI dasar dan semua kontribusi dari stall: Pipelineline CPI = Pipelineline ideal CPI + Struktural stall + Hambatan bahaya data + Kendala control Gambar 3.1 Teknik utama yang diperiksa pada Lampiran C, Bab 3, dan Lampiran H diperlihatkan bersamaan dengan komponen persamaan CPI yang mempengaruhi teknik ini. CPI pipeline ideal adalah ukuran kinerja maksimal yang dapat dicapai oleh  penerapannya. Dengan mengurangi masing-masing persyaratan dari sisi kanan, kami mengurangi keseluruhan jalur pipeline CPI atau, sebaliknya, meningkatkan IPC (instruksi per jam). Persamaan di atas memungkinkan kita untuk mengkarakterisasi  berbagai teknik dengan komponen apa dari CPI keseluruhan yang dikurangi teknik. Gambar 3.1 menunjukkan teknik yang kami teliti dalam bab ini dan di Lampiran H,

serta topik yang dibahas dalam materi pengantar di Lampiran C. Dalam bab ini, kita akan melihat bahwa teknik yang kita perkenalkan untuk mengurangi pipeline ideal CPI dapat meningkatkan pentingnya mengatasi bahaya.

Apa itu Instruction-Level Parallelism?

Semua teknik dalam bab ini mengeksploitasi paralelisme di antara instruksi. Jumlah paralelisme yang tersedia di dalam blok dasar - urutan kode garis lurus tanpa cabang kecuali untuk masuk dan tidak ada cabang kecuali di pintu keluar - cukup kecil. Untuk program MIPS yang khas, frekuensi cabang dinamis rata-rata seringkali antara 15% dan 25%, yang berarti bahwa antara tiga dan enam instruksi dijalankan di antara sepasang cabang. Karena petunjuk ini cenderung saling bergantung satu sama lain,  jumlah tumpang tindih yang dapat kita eksploitasi ekspl oitasi dalam blok dasar cenderung kurang dari ukuran blok dasar rata-rata. Untuk mendapatkan peningkatan kinerja yang substansial, kita harus memanfaatkan ILP di beberapa b eberapa blok dasar. Cara termudah dan paling umum untuk meningkatkan ILP adalah dengan memanfaatkan paralelisme di antara iterasi loop. Jenis paralelisme ini sering disebut loop-level parallelism. Berikut adalah contoh sederhana dari sebuah loop yang menambahkan dua elemen 1000-elemen array dan benar-benar pararel: for (i=0; i=0; i=i 1)  – 

x[i] = x[i] + s;

Kita dapat melihat bahwa loop ini sejajar dengan memperhatikan bahwa tubuh setiap iterasi bersifat independen. Kami meresmikan gagasan ini di Lampiran H dan menjelaskan bagaimana kita dapat menguji apakah pengulangan loop independen pada waktu kompilasi. Pertama, mari kita lihat kinerja loop ini, menunjukkan bagaimana kita dapat menggunakan paralelisme untuk meningkatkan kinerjanya pada jaringan pipeline MIPS dengan latensi yang ditunjukkan di atas. Langkah pertama adalah menerjemahkan segmen di atas ke bahasa assembly MIPS. Pada segmen kode berikut, R1 pada awalnya adalah alamat elemen dalam array

dengan alamat tertinggi, dan F2 berisi nilai skalar s. Daftar R2 didahului, sehingga 8 (R2) adalah alamat dari elemen terakhir yang beroperasi. Instruksi memproduksi hasil

Intruksi menggunakanan hasil

Latensi

dalam siklus clock FP ALU op FP ALU op lain

3

FP ALU op Store double 2 Load double FP ALU op 1 Load double Store double 0 Gambar 3.2 Latensi operasi FP yang digunakan dalam bab ini. Kolom terakhir adalah jumlah siklus jam intervensi yang diperlukan untuk menghindari stals. Angka-angka ini mirip dengan latensi rata-rata yang akan kita lihat  pada unit FP. Latensi muatan floating-point ke penyimpanan adalah 0, karena hasil loads

dapat

dilewati

tanpa

mengulur-ulur

penyimpanan.

Kami

akan

terus

mengasumsikan latensi loads integer 1 dan latensi ALU integer 0. Kode MIPS langsung, tidak dijadwalkan untuk pipeline, terlihat seperti ini: Loop:

L.D F0,0(R1)

ADD.D

;F0=array element

F4,F0,F2

;add scalar in F2

S.D

F4,0(R1)

;store result

DADDUI

R1,R1,#-8

;decrement pointer ;8 bytes (per DW)

BNE

R1,R2,Loop

;branch R1!=R2

Mari mulai dengan melihat seberapa baik loop ini akan berjalan saat dijadwalkan  pada jalur pipeline sederhana untuk MIPS dengan latensi dari Gambar 3.2. Contoh Tunjukkan bagaimana loop akan terlihat pada MIPS, keduanya terjadwal dan tidak terjadwal, termasuk stall atau siklus jam menganggur. Jadwalkan penundaan operasi floating-point, namun ingatlah bahwa kami mengabaikan cabang yang tertunda. Jawab

Tanpa penjadwalan apapun, loop akan mengeksekusi sebagai

 berikut, mengambil sembilan siklus: Siklus jam dikeluarkan

Loop: stall

L.D

F0,0(R1) 2

1

ADD.D

F4,F0,F2

stall

4

stall

5

S.D

F4,0(R1)

6

DADDUI

R1,R1,#-8

7

stall BNE

3

8 R1,R2,Loop 9

Kita bisa menjadwalkan loop untuk mendapatkan hanya dua stalls dan mengurangi waktu menjadi tujuh siklus: Loop:

L.D F0,0(R1)

DADDUI

R1,R1,#-8

ADD.D

F4,F0,F2

stall stall S.D

F4,8(R1)

BNE

R1,R2,Loop

Stalls setelah ADD.D digunakan untuk S.D.

Pada contoh sebelumnya, kita menyelesaikan satu iterasi loop dan menyimpan satu elemen array setiap tujuh siklus clock, namun kerja sebenarnya dari operasi pada elemen array hanya membutuhkan tiga (loads, penambahan, dan penyimpanan) dari tujuh siklus clock tersebut. Siklus empat jam tersisa terdiri dari overhead loopDADDUI dan BNE-dan dua stalls. Untuk menghilangkan empat siklus clock ini, kita  perlu mendapatkan lebih banyak operasi dibandingkan dengan jumlah instruksi overhead. Skema sederhana untuk meningkatkan jumlah instruksi relatif terhadap instruksi cabang dan overhead adalah loop unrolling. Membuka gulungan hanya mereplikasi tubuh lingkaran beberapa kali, menyesuaikan kode penghentian loop.

Loop unrolling juga bisa digunakan untuk memperbaiki penjadwalan. Karena menghilangkan cabang, memungkinkan instruksi dari berbagai iterasi untuk dijadwalkan bersama. Dalam hal ini, kita bisa menghilangkan data menggunakan stalls dengan membuat tambahan instruksi independen di dalam body loop. Jika kita hanya mereplikasi instruksi saat membuka unrolled loop, penggunaan register yang sama dapat mencegah kita untuk secara efektif menjadwalkan loop. Dengan demikian, kita akan ingin menggunakan register yang berbeda untuk setiap iterasi, meningkatkan  jumlah register yang dibutuhkan.

Contoh Tunjukkan loop yang tidak tergulung (unrolled loop) sehingga ada empat salinan dari isi loop, dengan asumsi R1 - R2 (yaitu ukuran array) pada awalnya merupakan kelipatan 32, yang berarti bahwa jumlah pengulangan loop adalah kelipatan dari 4. Hilangkan perhitungan yang sangat berlebihan dan jangan gunakan kembali pada register mana pun. Answer

Inilah hasilnya setelah menggabungkan instruksi DADDUI dan

membuang operasi BNE, yang tidak perlukan, yang diduplikasi saat membuka gulungan. Perhatikan bahwa R2 yang sekarang harus disetel sehingga 32 (R2) adalah alamat awal dari empat elemen terakhir. Loop: ADD.D

L.D

F0,0(R1) F4,F0,F2

S.D

F4,0(R1)

L.D

F6,-8(R1)

ADD.D

F8,F6,F2

S.D

F8,-8(R1)

L.D

F10,-16(R1)

ADD.D

;drop DADDUI & BNE

;drop DADDUI & BNE

F12,F10,F2

S.D

F12,-16(R1) ;drop DADDUI & BNE

L.D

F14,-24(R1)

ADD.D

F16,F14,F2

S.D

F16,-24(R1)

DADDUI

R1,R1,#-32

BNE

R1,R2,Loop

Kita telah menghilangkan tiga cabang dan tiga deret R1. Alamat pada loads dan  penyimpanan telah diberi kompensasi untuk memungkinkan instruksi DADDUI di R1 digabungkan. Pengoptimalan ini mungkin tampak sepele, tapi tidak demikian; Hal itu membutuhkan penggantian dan penyederhanaan simbolis. Substitusi simbolis dan  penyederhanaan akan mengatur ulang ungkapan-ungkapan sehingga memungkinkan konstanta menjadi runtuh, memungkinkan ungkapan seperti ((i + 1) + 1) ditulis ulang sebagai (i + (1 + 1)) dan kemudian disederhanakan menjadi (i + 2). Kita akan melihat  bentuk pengoptimalan yang lebih umum yang menghilangkan perhitungan dependen  pada Lampiran H. Tanpa penjadwalan, setiap operasi dalam unrolled loop diikuti oleh operasi yang dependen dan dengan demikian akan menyebabkan sebuah stalls. Lingkaran ini akan  berjalan dalam 27 siklus clock - setiap LD memiliki 1 stall, masing-masing ADDD 2, siklus instruksi DADDUI 1, plus 14 siklus instruksi instruksi - atau 6,75 jam untuk masing-masing dari empat elemen, namun dapat dijadwalkan untuk meningkatkan kinerja secara signifikan. Unrolling loop biasanya dilakukan di awal proses kompilasi, sehingga perhitungan berlebihan bisa terpapar dan dieliminasi oleh pengoptimasi. Dalam program nyata kita biasanya tidak tahu batas atas pada loop. Misalkan n, dan kita ingin unrolling loop untuk membuat salinan dari isi. Alih-alih satu loop unrolled, kita menghasilkan sepasang loop berturut-turut. Waktu eksekusi pertama (n mod k) dan memiliki isi yang merupakan loop asli. Yang kedua adalah isi yang tidak tergali dikelilingi oleh lingkaran luar yang mengulangi (n / k) kali. (Seperti yang akan kita lihat di Bab 4, teknik ini serupa dengan teknik yang disebut penambangan strip, yang digunakan pada kompiler untuk prosesor vektor.) Untuk nilai n yang besar, sebagian besar waktu eksekusi akan dihabiskan di badan loop unrolled. Pada contoh sebelumnya, unrolling meningkatkan kinerja loop ini dengan menghilangkan instruksi overhead, meskipun meningkatkan ukuran kode secara substansial. Bagaimana kinerja loop yang tidak dibuka saat dijadwalkan untuk pipeline yang dijelaskan sebelumnya? Contoh

Tampilkan loop unrolled pada contoh sebelumnya setelah

dijadwalkan untuk pipeline dengan latensi dari Gambar 3.2. Jawab Loop:

L.D

F0,0(R1)

L.D

F6,-8(R1)

L.D

F10,-16(R1)

L.D

F14,-24(R1)

ADD.D

F4,F0,F2

ADD.D

F8,F6,F2

ADD.D

F12,F10,F2

ADD.D

F16,F14,F2

S.D

F4,0(R1)

S.D

F8,-8(R1)

DADDUI

R1,R1,#-32

S.D

F12,16(R1)

S.D

F16,8(R1)

BNE

R1,R2,Loop

Waktu eksekusi loop unrolled telah turun menjadi, total 14 clock cycle, atau 3,5 clock cycle per element, dibandingkan dengan 9 cycle per element sebelum ada unrolling atau penjadwalan dan 7 cycle saat terjadwal namun tidak dibuka.  bahkan keuntungan dari penjadwalan pada loop unrolled lebih besar dari pada loop

asli.

Peningkatan

memperlihatkan

lebih

ini

muncul

banyak

karena

perhitungan

membuka yang

loop

dapat

unrolling

dijadwalkan

yang untuk

meminimalkan stalls; Kode diatas tidak memiliki stalls. Penjadwalan loop dengan cara ini mengharuskan menyadari bahwa loads dan penyimpanan bersifat independen dan dapat dipertukarkan.

Ringkasan dari Loop Unrolling and Penjadwalan

Sepanjang bab ini dan Lampiran H, kita akan melihat berbagai teknik perangkat keras dan perangkat lunak yang memungkinkan kita untuk memanfaatkan paralelisme tingkat instruksi untuk memanfaatkan sepenuhnya potensi unit fungsional dalam  prosesor. Kunci sebagian besar teknik ini adalah mengetahui kapan dan bagaimana  pemesanan di antara instruksi dapat diubah. Dalam contoh, kita membuat banyak  perubahan seperti itu, yang bagi kita, sebagai manusia, jelas diijinkan. Dalam

 prakteknya, proses ini harus dilakukan secara metodis baik oleh kompilator atau oleh  perangkat keras. Untuk mendapatkan kode akhir unrolled, kami harus membuat keputusan dan transformasi berikut: •

Tentukan bahwa unrolling loop akan berguna dengan menemukan bahwa

iterasi loop bersifat independen, kecuali untuk kode pemeliharaan loop. •

Gunakan register yang berbeda untuk menghindari kendala yang tidak

 perlu yang akan dipaksa dengan menggunakan register yang sama untuk perhitungan yang berbeda (mis., Ketergantungan nama). •

Hilangkan tes ekstra dan instruksi cabang dan sesuaikan penghenti loop

dan kode iterasi. •

Tentukan bahwa loads dan penyimpanan di loop yang tidak tergulung

dapat dipertukarkan dengan mengamati bahwa loads dan penyimpanan dari iterasi yang  berbeda bersifat independen. Transformasi ini memerlukan analisis alamat memori dan menemukan bahwa mereka tidak mengacu ke alamat yang sama. •

Jadwalkan kode, lestarikan ketergantungan yang diperlukan untuk

menghasilkan hasil yang sama seperti kode asli. Persyaratan utama yang mendasari semua transformasi ini adalah pemahaman tentang bagaimana satu instruksi bergantung pada yang lain dan bagaimana instruksinya dapat diubah atau disusun ulang mengingat ketergantungannya. Tiga efek yang berbeda membatasi keuntungan dari loop unrolling: (1)  penurunan jumlah overhead yang diamortisasi dengan masing-masing gulungan, (2)  batasan ukuran kode, dan (3) keterbatasan kompilator. Mari kita pertimbangkan  pertanyaan tentang overhead loop terlebih dahulu. Ketika kita membuka gulungan loop empat kali, itu menghasilkan paralelisme yang cukup di antara instruksi bahwa loop  bisa dijadwalkan tanpa siklus stalls. Sebenarnya, dalam 14 siklus clock, hanya 2 siklus yaitu loop overhead: DADDUI, yang mempertahankan nilai indeks, dan BNE, yang mengakhiri loop. Jika loop dibuka dua kali lipat, overhead dikurangi dari 1/2 siklus per iterasi asli menjadi 1/4. Batas kedua untuk unrolling adalah pertumbuhan dalam ukuran kode yang dihasilkan. Untuk loop yang lebih besar, ukuran kode mungkin menjadi perhatian terutama jika menyebabkan peningkatan tingkat kehilangan cache instruksi.

Faktor lain yang sering kali lebih penting daripada ukuran kode adalah kekurangan potensial pada register yang dibuat dengan unrolling dan scheduling yang agresif. Efek sekunder yang dihasilkan dari penjadwalan instruksi pada segmen kode  besar disebut regresi register. Timbul karena kode penjadwalan untuk meningkatkan ILP menyebabkan jumlah nilai hidup meningkat. Setelah penjadwalan instruksi yang agresif, mungkin tidak memungkinkan untuk mengalokasikan semua nilai live ke register. Kode yang berubah, sementara secara teoritis lebih cepat, mungkin kehilangan  beberapa atau semua keuntungannya karena menghasilkan kekurangan register. Tanpa membuka gulungan, penjadwalan agresif cukup dibatasi oleh cabang sehingga tekanan register jarang menjadi masalah. Kombinasi penjadwalan ulang dan penjadwalan dapat menyebabkan masalah ini. Masalahnya menjadi sangat menantang dalam prosesor multi masalah yang memerlukan pemaparan urutan instruksi yang lebih independen yang eksekusi dapat tumpang tindih. Secara umum, penggunaan transformasi tingkat tinggi yang canggih, yang perbaikan potensialnya sulit diukur sebelum pembuatan kode terperinci, telah menyebabkan peningkatan kompleksitas kompiler modern yang signifikan. Loop unrolling adalah metode sederhana namun berguna untuk meningkatkan ukuran fragmen kode garis lurus yang dapat dijadwalkan secara efektif. Transformasi ini berguna dalam berbagai prosesor, mulai dari jaringan pipeline sederhana seperti yang telah kita pelajari sejauh ini dengan superscalars multipel dan VLIW yang dieksplorasi nanti di bab ini.

Mengurangi Biaya Cabang dengan Prediksi Cabang Lanjutan

Karena kebutuhan untuk menerapkan ketergantungan kontrol melalui bahaya cabang dan stalls, cabang akan merusak kinerja jaringan pipeline. Loop unrolling adalah salah satu cara untuk mengurangi jumlah bahaya cabang; Kita juga bisa mengurangi kerugian kinerja cabang dengan meramalkan bagaimana mereka akan berperilaku. Pada Lampiran C, kami memeriksa prediktor cabang sederhana yang mengandalkan informasi kompilasi atau pada perilaku dinamis teramati dari cabang yang diisolasi. Karena jumlah instruksi dalam penerbangan telah meningkat, semakin penting prediksi

cabang yang lebih akurat. Pada bagian ini, kami memeriksa teknik untuk meningkatkan akurasi prediksi dinamis.

Prediktor Cabang Korelasi

Skema prediktor 2-bit hanya menggunakan perilaku terkini cabang tunggal untuk memprediksi perilaku masa depan cabang tersebut. Ada kemungkinan untuk memperbaiki akurasi prediksi jika kita juga melihat perilaku cabang baru belakangan ini, bukan hanya cabang yang ingin kita prediksi. Pertimbangkan fragmen kode kecil dari patokan eqntott, anggota suite benchmark SPEC awal yang menunjukkan perilaku  prediksi cabang yang sangat buruk: if (aa==2) aa=0; if (bb==2)  bb=0; if (aa!=bb) { Berikut adalah kode MIPS yang biasanya kami buat untuk fragmen kode ini dengan asumsi bahwa aa dan bb ditugaskan untuk register R1 dan R2: DADDIU

R3,R1,# 2  – 

BNEZ

R3,L1

DADD

R1,R0,R0

;branch b1

(aa!=2)

;branch b2

(bb!=2)

;aa=0

L1: DADDIU

R3,R2,# 2  – 

BNEZ

R3,L2

DADD

R2,R0,R0

L2: BEQZ

DSUBU

;bb=0 R3,R1,R2

R3,L3

;R3=aa-bb ;branch b3

(aa==bb)

Mari kita label cabang-cabang ini b1, b2, dan b3. Pengamatan kunci adalah  bahwa perilaku cabang b3 berkorelasi dengan perilaku cabang b1 dan b2. Jelas, jika cabang b1 dan b2 sama-sama tidak diambil (yaitu, jika kondisinya baik dievaluasi ke true dan aa dan bb keduanya ditugaskan 0), maka b3 akan diambil, karena aa dan bb

 jelas sama. Prediktor yang hanya menggunakan perilaku cabang tunggal untuk memprediksi hasil cabang itu tidak akan pernah bisa menangkap perilaku ini. Prediktor cabang yang menggunakan tingkah laku cabang lainnya membuat  prediksi disebut correlating predictors atau two-level predictors. Prediktor berkorelasi yang ada menambahkan informasi tentang perilaku cabang terbaru untuk menentukan  bagaimana memprediksi cabang yang diberikan. Sebagai contoh, prediktor (1,2) menggunakan perilaku cabang terakhir untuk memilih dari antara sepasang prediktor cabang 2-bit dalam memprediksi cabang tertentu. Dalam kasus umum, prediktor (m, n) menggunakan perilaku cabang m terakhir untuk memilih dari prediktor cabang 2m, yang masing-masing merupakan prediktor n-bit untuk cabang tunggal. Daya tarik jenis  peramalan cabang yang berkorelasi ini adalah bahwa ia dapat menghasilkan tingkat  prediksi yang lebih tinggi daripada skema 2-bit dan hanya membutuhkan sejumlah  perangkat keras tambahan sepele. Kesederhanaan perangkat keras berasal dari pengamatan sederhana: Sejarah global dari cabang m terbaru dapat dicatat dalam register geser m-bit, di mana masingmasing bit mencatat apakah cabang diambil atau tidak diambil. Penyangga prediksi cabang kemudian dapat diindeks dengan menggunakan rangkaian bit loworder dari alamat cabang dengan sejarah global m-bit. Sebagai contoh, pada buffer (2,2) dengan total 64 entri, 4 bit alamat low-order dari cabang (word address) dan 2 bit global yang mewakili perilaku dari dua cabang yang terakhir dieksekusi membentuk 6 bit Index yang bisa digunakan untuk mengindeks 64 counter. Seberapa jauhkah detektor cabang yang bekerja berkorelasi bila dibandingkan dengan skema 2-bit standar? Untuk membandingkannya dengan cukup, kita harus membandingkan prediktor yang menggunakan jumlah bit negara yang sama. Jumlah bit dalam prediktor (m, n) adalah 2m × n × Jumlah entri prediksi yang dipilih oleh alamat cabang Prediktor 2-bit tanpa sejarah global hanyalah prediktor (0,2).

Contoh

Berapa banyak bit yang ada pada prediktor cabang (0,2) dengan

entri 4K? Berapa banyak entri yang berada dalam prediktor (2.2) dengan jumlah bit yang sama?

Jawab Prediktor dengan entri 4K memiliki 20 × 2 × 4K = 8K bits Berapa banyak entri cabang terpilih berada pada prediktor (2.2) yang memiliki total 8K bit dalam buffer prediksi? Kita tahu itu 22 × 2 × Jumlah entri prediksi yang dipilih oleh cabang = 8K Oleh karena itu, jumlah entri prediksi dipilih oleh cabang = 1K. Gambar 3.3 membandingkan tingkat kesalahpahaman prediktor sebelumnya (0,2) dengan entri 4K dan prediktor (2,2) dengan entri 1K. Seperti yang dapat Anda lihat, prediktor yang berkorelasi ini tidak hanya mengungguli prediktor 2-bit sederhana dengan jumlah bit negara yang sama, namun juga sering melampaui prediktor 2-bit dengan jumlah entri yang tidak terbatas. Prediktor Turnamen: Menggabungkan Prediktor Lokal dan Global secara Adaptif Motivasi utama untuk menghubungkan prediktor cabang berasal dari  pengamatan adalah prediktor 2-bit standar yang hanya menggunakan informasi lokal gagal pada beberapa cabang penting dan, dengan menambahkan informasi global, kinerjanya dapat ditingkatkan. Prediktor turnamen mengambil wawasan ini ke tingkat  berikutnya, dengan menggunakan beberapa prediktor, biasanya satu berdasarkan informasi global dan satu berdasarkan informasi lokal, dan menggabungkann ya dengan  pemilih. Prediktor turnamen dapat mencapai akurasi yang lebih baik dengan ukuran sedang (8K-32K bit) dan juga menggunakan jumlah bit prediksi yang sangat besar secara efektif. Prediktor turnamen yang ada menggunakan penghitung jenuh 2-bit per cabang untuk memilih di antara dua prediktor yang berbeda berdasarkan prediktor (lokal, global, atau bahkan beberapa campuran) yang paling efektif dalam prediksi baru baru ini. Seperti pada prediktor 2-bit sederhana, penghitung jenuh memerlukan dua kesalahan prediksi sebelum mengubah identitas prediktor pilihan. Keuntungan dari  prediktor turnamen adalah kemampuannya untuk memilih prediktor yang tepat untuk cabang tertentu, yang sangat penting untuk tolok ukur int eger. Prediktor turnamen yang khas akan memilih prediktor global hampir 40% dari waktu untuk benchmark integer SPEC dan kurang dari 15% waktu untuk benchmark SPEC FP. Selain prosesor Alpha

yang mempelopori prediksi turnamen, prosesor AMD terbaru, termasuk Opteron dan Phenom, telah menggunakan prediktor bergaya turnamen. Gambar 3.3 Perbandingan prediktor 2 bit. Prediktor yang tidak berkorelasi untuk 4096 bit pertama, diikuti oleh prediktor 2-bit yang tidak berkorelasi dengan entri tak terbatas dan prediktor 2 bit dengan 2 bit riwayat global dan total 1024 entri. Meskipun data ini untuk versi SPEC yang lebih lama, data untuk benchmark SPEC yang lebih  baru akan menunjukkan perbedaan akurasi yang sama. Jumlah bit menggunakan SPEC89 sebagai benchmark. Seperti yang kita lihat sebelumnya, kemampuan prediksi prediktor lokal tidak membaik melebihi ukuran tertentu. Prediktor yang berkorelasi menunjukkan peningkatan yang signifikan, dan  prediksi turnamen menghasilkan kinerja yang sedikit lebih baik. Untuk versi SPEC yang lebih baru, hasilnya akan serupa, namun perilaku asimtotik tidak akan tercapai sampai ukuran prediktor sedikit lebih besar. Prediktor lokal terdiri dari prediktor dua level. Tingkat atas adalah tabel sejarah lokal yang terdiri dari 1024 entri 10-bit; Setiap entri 10 bit sesuai dengan 10 hasil cabang terbaru untuk entri. Artinya, jika cabang diambil 10 kali atau lebih berturut-turut, entri dalam tabel sejarah lokal akan menjadi 1s. Jika cabang diambil dan diambil secara bergantian, entri sejarah terdiri dari alternating 0s dan 1s. Sejarah 10-bit ini memungkinkan pola hingga 10 cabang ditemukan dan diprediksi. Entri yang dipilih dari tabel sejarah lokal digunakan untuk mengindeks tabel entri 1K yang terdiri dari penghitung saturasi 3 bit, yang memberikan  prediksi lokal. Kombinasi ini, yang menggunakan total 29K bit, menyebabkan akurasi yang tinggi dalam prediksi cabang. Gambar 3.4 Tingkat salah prediksi untuk tiga prediktor yang berbeda pada SPEC89 karena jumlah bit meningkat. Prediktor adalah prediktor 2-bit lokal, prediktor korelasi yang terstruktur secara optimal dalam penggunaan informasi global dan lokal  pada setiap titik dalam grafik, dan prediksi turnamen. Meskipun data ini untuk versi SPEC yang lebih lama, data untuk benchmark SPEC yang lebih baru akan menunjukkan  perilaku serupa, mungkin konvergen ke batas asimtotik pada ukuran prediktor yang sedikit lebih besar.

Prediktor Cabang Intel Core i7

Intel telah merilis hanya sejumlah informasi terbatas tentang prediksi cabang Core i7, yang didasarkan pada prediktor sebelumnya yang digunakan pada chip Core Duo. I7 menggunakan prediktor dua tingkat yang memiliki prediktor tingkat pertama yang lebih kecil, yang dirancang untuk memenuhi batasan siklus memprediksi cabang setiap siklus clock, dan prediktor tingkat kedua yang lebih besar sebagai cadangan. Setiap prediktor menggabungkan tiga prediktor yang berbeda: (1) prediktor dua bit sederhana, yang diperkenalkan pada Lampiran C (dan digunakan dalam prediksi turnamen yang dibahas di atas); (2) prediktor sejarah global, seperti yang baru saja kita lihat; Dan (3) prediksi keluar loop. Prediktor loop keluar menggunakan counter untuk memprediksi jumlah cabang yang diambil (yang merupakan jumlah loop pengulangan) untuk cabang yang terdeteksi sebagai cabang lingkaran. Untuk setiap cabang, prediksi terbaik dipilih dari tiga prediktor dengan melacak keakuratan setiap prediksi, seperti  prediksi turnamen. Selain prediktor utama bertingkat ini, unit terpisah memprediksi alamat target untuk cabang tidak langsung, dan tumpukan untuk memprediksi alamat  pengirim juga digunakan.

Gambar 3.5 Tingkat kesalahpahaman untuk 19 dari benchmark SPECCPU2006 versus jumlah cabang yang berhasil dipekerjakan sedikit lebih tinggi rata-rata untuk tolok ukur integer daripada FP (4% versus 3%). Lebih penting l agi, ini jauh lebih tinggi untuk beberapa tolok ukur. Seperti dalam kasus lain, spekulasi menyebabkan beberapa tantangan dalam mengevaluasi prediktor, karena cabang yang salah diketahui dapat dengan mudah mengarah ke cabang lain yang diambil dan salah paham. Untuk menjaga hal-hal sederhana, kita melihat jumlah mispredictions sebagai persentase dari jumlah cabang yang berhasil diselesaikan (yang bukan hasil dari misspeculation). Gambar 3.5 menunjukkan data ini untuk 19 benchmark SPECCPU 2006. Tolok ukur ini jauh lebih  besar dari SPEC89 atau SPEC2000, dengan akibatnya tingkat kesalahpahaman sedikit lebih tinggi daripada pada Gambar 3.4 bahkan dengan kombinasi prediktor yang lebih rumit. Karena misprediksi cabang mengarah pada spekulasi yang tidak efektif, hal itu  berkontribusi pada terbuangnya pekerjaan, seperti yang akan kita lihat nanti di bab ini.

Mengatasi Bahaya Data dengan Penjadwalan Dinamis

Sebuah pipeline statis yang dijadwalkan secara statistik mengambil sebuah instruksi dan mengeluarkannya, kecuali ada ketergantungan data antara instruksi yang sudah ada dalam pipeline dan instruksi yang tidak dapat disembunyikan dengan melewati atau meneruskan. (Forwarding logic mengurangi latensi pipelin e yang efektif sehingga

ketergantungan

tertentu

tidak

mengakibatkan

bahaya.)

Jika

ada

ketergantungan data yang tidak dapat disembunyikan, maka perangkat keras deteksi  bahaya memadamkan jaringan pipeline yang dimulai dengan instruksi yang menggunakan hasilnya. Tidak ada instruksi baru yang diambil atau dikeluarkan sampai ketergantungan tersebut dihapus. Pada bagian ini, kita mengeksplorasi penjadwalan dinamis, di mana perangkat keras

mengatur

ulang

eksekusi

instruksi

untuk

mengurangi

stalls

sambil

mempertahankan aliran data dan perilaku pengecualian. Penjadwalan dinamis menawarkan beberapa keuntungan. Pertama, ini memungkinkan kode yang disusun dengan satu pipeline agar berjalan efisien pada jalur pipeline yang berbeda, sehingga menghilangkan kebutuhan untuk memiliki banyak binari dan mengkompilasi ulang untuk mikroarsitektur yang berbeda. Di lingkungan komputasi saat ini, di mana sebagian besar perangkat lunak berasal dari pihak ketiga dan didistribusikan dalam  bentuk biner, keuntungan ini signifikan. Kedua, memungkinkan penanganan beberapa kasus bila ketergantungan tidak diketahui pada waktu kompilasi; Misalnya, mereka mungkin melibatkan referensi memori atau cabang yang bergantung pada data, atau mungkin dihasilkan dari lingkungan pemrograman modern yang menggunakan tautan dinamis atau pengiriman. Ketiga, dan mungkin yang terpenting, ini memungkinkan  prosesor untuk mentolerir penundaan yang tidak dapat diprediksi, seperti cache misses, dengan

mengeksekusi

kode

lainnya

sambil

menunggu

ketinggalan

untuk

menyelesaikannya. Pada Bagian 3.6, kami mengeksplorasi spekulasi perangkat keras, teknik dengan keuntungan kinerja tambahan, yang dibangun berdasarkan penjadwalan dinamis. Seperti yang akan kita lihat, keuntungan penjadwalan dinamis diperoleh dengan biaya peningkatan kompleksitas perangkat keras yang signifikan.

Meskipun prosesor yang dijadwalkan secara dinamis tidak dapat mengubah arus data, ia mencoba untuk menghindari mengulur-ulur saat ada ketergantungan. Sebaliknya, penjadwalan pipeline statis oleh kompilator (dibahas di Bagian 3.2) mencoba untuk meminimalkan stalls dengan memisahkan instruksi yang dependen sehingga tidak menimbulkan bahaya. Tentu saja, penjadwalan pipeline kompilator juga dapat digunakan pada kode yang ditujukan untuk berjalan pada prosesor dengan  pipeline yang dijadwalkan secara dinamis.

Penjadwalan Dinamis: Ide Keterbatasan utama teknik pipelining sederhana adalah bahwa mereka menggunakan instruksi-instruksi dan eksekusi dalam urutan: Instruksi dikeluarkan dalam urutan program, dan jika instruksi dihentikan dalam pipeline, instruksi selanjutnya tidak dapat dilanjutkan. Jadi, jika ada ketergantungan antara dua instruksi  jarak dekat dalam pipeline, ini akan menyebabkan bahaya dan stalls akan berakibat. Jika ada beberapa unit fungsional, unit ini bisa menganggur. Jika instruksi j bergantung  pada instruksi yang berjalan lama, saat ini dalam eksekusi di dalam pipeline, maka semua instruksi setelah j harus terhenti sampai selesai dan j dapat dijalankan. Misaln ya,  perhatikan kode ini: DIV.D

F0,F2,F4

ADD.D

F10,F0,F8

SUB.D

F12,F8,F14

Instruksi SUB.D tidak dapat dijalankan karena ketergantungan ADD.D pada DIV.D menyebabkan jaringan pipeline berhenti; Namun, SUB.D bukan data tergantu ng  pada apapun dalam pipeline. Bahaya ini menciptakan batasan kinerja yang dapat dieliminasi dengan tidak memerlukan instruksi untuk dieksekusi dalam urutan program. Dalam pipeline lima tahap klasik, bahaya struktural dan data dapat diperiksa saat instruksi decode (ID): Bila instruksi dapat dijalankan tanpa bahaya, dikeluarkan dari ID karena mengetahui bahwa semua bahaya data telah teratasi.

Agar kita dapat mengeksekusi SUBD dalam contoh di atas, kita harus memisahkan proses penerbitan menjadi dua bagian: memeriksa bahaya struktural dan menunggu tidak adanya bahaya data. Jadi, kita masih menggunakan in -order instruction issue (yaitu instruksi yang dikeluarkan dalam urutan program), namun kami menginginkan sebuah instruksi untuk memulai eksekusi segera setelah operan datanya tersedia. Pipeline semacam itu melakukan eksekusi out-of-order, yang menyiratkan  penyelesaian out-of-order. Eksekusi di luar kebiasaan mengenalkan kemungkinan bahaya WAR dan WAW, yang tidak ada dalam pipeline integer lima tahap dan perpanjangan logisnya ke pipeline floating-point dalam pesanan. Perhatikan urutan kode floating-point MIPS berikut ini: DIV.D

F0,F2,F4

ADD.D

F6,F0,F8

SUB.D

F8,F10,F14

MUL.D

F6,F10,F8

Ada antidependensi antara ADD.D dan SUB.D, dan jika pipeline mengeksekusi SUBD

sebelum

ADD.D

(yang

menunggu

DIV.D),

maka

akan

melanggar

antidependensi, menghasilkan bahaya WAR . Demikian juga, untuk menghindari  penyalahgunaan keluaran, seperti penulisan F6 oleh MUL.D, bahaya WAW harus ditangani. Seperti yang akan kita lihat, kedua bahaya ini dihindari dengan penggunaan daftar nama pengganti. Penyelesaian

out-of-order

juga

menciptakan

komplikasi

utama

dalam

 penanganan pengecualian. Penjadwalan dinamis dengan penyelesaian out-of-order harus menjaga perilaku pengecualian dalam arti bahwa persis pengecualian yang akan muncul jika program dijalankan dalam urutan program yang ketat benar -benar muncul. Prosesor yang dijadwalkan secara dinamis mempertahankan perilaku pengecualian dengan menunda pemberitahuan pengecualian terkait sampai prosesor mengetahui  bahwa instruksinya seharusnya selesai berikutnya. Meskipun

perilaku

pengecualian

harus

dipertahankan,

prosesor

yang

dijadwalkan secara dinamis dapat menghasilkan pengecualian yang tidak tepat. Pengecualian tidak tepat jika status prosesor bila pengecualian dinaikkan tidak terlihat

 persis seperti jika instruksi dijalankan secara berurutan dalam urutan program yang ketat. Pengecualian yang tidak jelas dapat terjadi karena dua kemungkinan: 1.

Pipeline mungkin telah menyelesaikan instruksi yang kemudian dalam

urutan program daripada instruksi yang menyebabkan pengecualian. 2.

Pipeline mungkin belum menyelesaikan beberapa instruksi yang lebih

awal dalam urutan program daripada instruksi yang menyebabkan pengecualian. Pengecualian yang tidak tepat membuat sulit untuk memulai ulang eksekusi setelah pengecualian. Daripada mengatasi masalah tersebut di bagian ini, kita akan membahas sebuah solusi yang memberikan pengecualian yang tepat dalam konteks  prosesor dengan spekulasi di Bagian 3.6. Untuk pengecualian floating-point, solusi lain telah digunakan, seperti yang dibahas pada Lampiran J. Untuk mengijinkan eksekusi out-of-order, pada dasarnya kita membagi tahap  pipeline ID dari pipeline lima tingkat sederhana menjadi dua tahap: 1.

Instruksi Decode-Decode, periksa bahaya structural.

2.

Baca operan-Tunggu hingga tidak ada bahaya data, baca operan.

Tahap pengambilan instruksi mendahului tahap penerbitan dan dapat diambil  baik ke dalam register instruksi atau ke dalam antrian instruksi yang tertunda; Instruksi kemudian dikeluarkan dari register atau antrian. Tahap eksekusi mengikuti tahap operan  baca, sama seperti pada pipeline lima tahap. Eksekusi mungkin memakan banyak siklus, tergantung pada operasi. Kita membedakan kapan sebuah instruksi dimulai eksekusi dan kapan ia menyelesaikan eksekusi; Antara dua kali, instruksi sedang dalam eksekusi. Pipeline kami memungkinkan banyak instruksi untuk dieksekusi pada saat bersamaan; Tanpa kemampuan ini, keuntungan utama penjadwalan dinamis pun hilang. Memiliki banyak instruksi dalam eksekusi sekaligus membutuhkan beberapa unit fungsional, unit fungsional pipeline, atau keduanya. Karena dua kemampuan ini - unit fungsional  pipelined dan beberapa unit fungsional - pada dasarnya setara untuk tujuan kontrol  pipeline, kita akan menganggap prosesor memiliki beberapa unit fungsional. Dalam pipeline yang dijadwalkan secara dinamis, semua instruksi melewati tahap masalah secara berurutan (in-order issue); Namun, mereka dapat terhenti atau melewati satu sama lain di tahap kedua (read operands) dan dengan demikian masuk

eksekusi tidak sesuai urutan. Scoreboarding adalah teknik untuk mengizinkan instruksi agar tidak rusak bila ada sumber daya yang memadai dan tidak ada ketergantungan data; Ini dinamai CDC 6600 scoreboard, yang mengembangkan kemampuan ini. Di sini, kita fokus pada teknik yang lebih canggih, yang disebut algoritma Tomasulo. Perbedaan utama adalah bahwa algoritma Tomasulo menangani ketergantungan antidependensi dan keluaran dengan mengubah secara efektif register secara dinamis. Selain itu, algoritma Tomasulo dapat diperluas untuk menangani spekulasi, teknik untuk mengurangi efek ketergantungan kontrol dengan memprediksi hasil cabang, melaksanakan instruksi di alamat tujuan yang diprediksi, dan mengambil tindakan  perbaikan saat prediksi salah. Sementara penggunaan scoreboarding mungkin cukup untuk mendukung superscalar dua masalah sederhana seperti ARM A8, prosesor yang lebih agresif, seperti Intel I7 empat isu, mendapat keuntungan dari penggunaan eksekusi di luar pesanan.

Penjadwalan Dinamis Menggunakan Pendekatan Tomasulo

Unit floating-point IBM 360/91 menggunakan skema yang canggih untuk memungkinkan eksekusi out-of-order. Skema ini, yang ditemukan oleh Robert Tomasulo, dilacak saat operan mendapat instruksi tersedia untuk memini malkan bahaya RAW dan mengenalkan daftar nama di perangkat keras untuk meminimalkan bahaya WAW dan WAR. Ada banyak variasi pada skema ini dalam prosesor modern, walaupun konsep kunci untuk melacak ketergantungan instruksi memungkinkan eksekusi segera setelah operan tersedia dan mengganti nama register untuk menghindari bahaya WAR dan WAW adalah karakteristik umum. Tujuan IBM adalah untuk mencapai kinerja floating-point yang tinggi dari satu set instruksi dan dari kompiler yang dirancang untuk keseluruhan 360 keluarga komputer, bukan dari kompiler khusus untuk prosesor high-end. Arsitektur 360 hanya memiliki empat register floating-point presisi ganda, yang membatasi keefektifan  penjadwalan kompilator; Fakta ini merupakan motivasi lain untuk pendekatan Tomasulo. Selain itu, IBM 360/91 memiliki akses memori yang panjang dan penundaan floating-point yang panjang, yang algoritma Tomasulo dirancang untuk mengatasi.

Pada akhir bagian, kita akan melihat bahwa algoritma Tomasulo juga dapat mendukung eksekusi berulang dari beberapa iterasi satu lingkaran. Kami menjelaskan algoritma, yang berfokus pada unit floating-point dan unit loadstore, dalam konteks set instruksi MIPS. Perbedaan utama antara MIPS dan 360 adalah adanya instruksi register-memory pada arsitektur yang terakhir. Karena algoritma Tomasulo menggunakan unit fungsional loads, tidak ada perubahan signifikan yang diperlukan untuk menambahkan mode pengalamatan memori register. IBM 360/91 juga memiliki unit fungsional pipeline, bukan beberapa unit fungsional, namun kami menggambarkan algoritma tersebut seolah-olah ada beberapa unit fungsional. Ini adalah perpanjangan konseptual sederhana untuk j uga menyalurkan unit fungsional tersebut. Seperti yang akan kita lihat, bahaya RAW dihindari dengan mengeksekusi instruksi hanya jika operannya tersedia, itulah yang disediakan oleh pendekatan scoreboarding sederhana. Bahaya WAR dan WAW, yang timbul dari ketergantungan nama, dihilangkan dengan register renaming. Register renaming menghilangkan bahaya ini dengan mengganti nama semua register tujuan, termasuk yang membaca atau menulis yang tertunda untuk instruksi sebelumnya, sehingga penulisan di luar pesanan tidak mempengaruhi instruksi yang bergantung pada nilai operan sebelumnya. Untuk lebih memahami bagaimana mengganti nama register menghilangkan  bahaya WAR dan WAW, pertimbangkan urutan kode contoh berikut yang mencakup  potensi bahaya WAR dan WAW: DIV.D

F0,F2,F4

ADD.D

F6,F0,F8

S.D

F6,0(R1)

SUB.D

F8,F10,F14

MUL.D

F6,F10,F8

Ada dua antidependensi: antara ADD.D dan SUB.D dan antara S.D dan MUL.D. Ada juga ketergantungan output antara ADD.D dan MUL.D, yang menyebabkan tiga  bahaya yang mungkin terjadi: Bahaya pada penggunaan F8 oleh ADD.D dan  penggunaan F6 oleh SUBD, dan juga WAW Bahaya sejak ADD.D bisa selesai lebih

dari MUL.D. Ada juga tiga ketergantungan data sejati: antara DIV.D dan ADD.D, antara SUB.D dan MUL.D, dan antara ADD.D dan S.D. Ketergantungan nama ketiga ini bisa dihilangkan dengan register renaming. Untuk lebih mudahnya, asumsikan adanya dua register sementara, S dan T. Dengan menggunakan S dan T, urutannya dapat ditulis ulang tanpa ketergantungan seperti: DIV.D

F0,F2,F4

ADD.D

S,F0,F8

S.D

S,0(R1)

SUB.D

T,F10,F14

MUL.D

F6,F10,T

Selain itu, penggunaan selanjutnya F8 harus diganti oleh register T. Pada segmen kode ini, proses renaming dapat dilakukan secara statis oleh kompilator. Menemukan  penggunaan F8 yang nantinya ada dalam kode memerlukan analisis kompiler atau dukungan perangkat keras yang canggih, karena mungkin ada intervensi antara segmen kode di atas dan penggunaan F8 selanjutnya. Seperti yang akan kita lihat, algoritma Tomasulo dapat menangani renaming di cabang-cabang. Dalam skema Tomasulo, register renaming disediakan oleh reservation station, yang menyangga operan instruksi yang menunggu untuk dikeluarkan. Ide dasarnya adalah bahwa sebuah reservation station menjemput dan menyangga sebuah operan segera setelah tersedia, sehingga tidak perlu mendapatkan operan dari daftar. Selain itu, instruksi yang tertunda menunjuk reservation station yang akan memberi masukan mereka. Akhirnya, ketika berturut-turut menulis ke register tumpang tindih dalam eksekusi, hanya yang terakhir yang benar-benar digunakan untuk mengupdate register. Saat instruksi dikeluarkan, penspesifikasi register untuk operan yang tertunda diganti namanya menjadi nama reservation station, yang menyediakan renaming register. Ketika terdapat lebih banyak reservation station daripada register nyata, teknik ini bahkan dapat menghilangkan bahaya yang timbul dari ketergantungan nama yang tidak dapat dihilangkan oleh kompilator. Saat kita mengeksplorasi komponen skema Tomasulo, kita akan kembali ke topik penggantian nama dan melihat secara tepat  bagaimana penggantian nama terjadi dan bagaimana menghilangkan bahaya WAR dan WAW.

Penggunaan reservation station, bukan file register terpusat, menyebabkan dua  properti penting lainnya. Pertama, deteksi bahaya dan pengendalian eksekusi didistribusikan: Informasi yang tersimpan di reservation station di setiap unit fungsional menentukan kapan instruksi dapat dimulai eksekusi di unit tersebut. Kedua, hasil dilewatkan langsung ke unit fungsional dari reservation station dimana mereka disangga, daripada melalui register. Pelacakan ini dilakukan dengan bus hasil umum yang memungkinkan semua unit menunggu operan dimuat secara bersamaan (pada 360/91 ini disebut bus data biasa, atau CDB). Dalam jaringan pipeline dengan beberapa unit eksekusi dan mengeluarkan beberapa instruksi per jam, lebih dari satu bus hasil akan dibutuhkan. Gambar 3.6 menunjukkan struktur dasar prosesor berbasis Tomasulo, termasuk unit floating-point dan unit muatan / penyimpanan; Tidak ada tabel kontrol eksekusi yang ditampilkan. Setiap reservation station memegang instruksi yang telah dikeluarkan dan sedang menunggu eksekusi di unit fungsional dan nilai operan untuk instruksi tersebut, jika sudah dihitung, atau nama reservation station yang akan memberikan nilai operan.

Gambar 3.6 Struktur dasar unit floating-point MIPS menggunakan algoritma Tomasulo. Instruksi dikirim dari unit instruksi ke dalam antrian instruksi dari mana mereka dikeluarkan dalam urutan keluar pertama (FIFO). Reservation station mencakup operasi dan operan aktual, serta informasi yang digunakan untuk mendeteksi dan mengatasi bahaya. Load buffer memiliki tiga fungsi: (1) pegang komponen dari alamat efektif sampai dihitung, (2) lacak muatan luar biasa yang menunggu memori, dan (3) tahan hasil loads yang telah selesai yang menunggu CDB . Demikian pula, store buffer memiliki tiga fungsi: (1) pegang komponen dari alamat efektif sampai dihitung, (2) tahan alamat memori tujuan dari penyimpanan luar biasa yang menunggu nilai data disimpan, dan (3) tahan Alamat dan nilai untuk disimpan sampai unit memori tersedia. Semua hasil dari unit FP atau unit loads diletakkan di CDB, yang masuk ke file register FP dan juga ke reservation station dan store buffer. Penambah FP menerapkan  penambahan dan pengurangan, dan pengganda FP melakukan perkalian dan pembagian.

Penyangga buffer dan store buffer menyimpan data atau alamat yang berasal dari dan pergi ke memori dan berperilaku hampir persis seperti reservation station , jadi kami membedakannya hanya jika diperlukan. Register floating-point dihubungkan oleh sepasang bus ke unit fungsional dan oleh bus tunggal ke store buffer. Semua hasil dari unit fungsional dan dari memori dikirim pada bus data umum, yang berjalan kemanamana kecuali ke load buffer. Semua reservation station memiliki kolom tag, dipekerjakan oleh kontrol pipeline. Sebelum kita menjelaskan rincian reservation station dan algoritma, mari kita lihat langkah-langkah yang diikuti sebuah instruksi. Hanya ada tiga langkah, meskipun masing-masing sekarang bisa mengambil jumlah siklus jam yang sewenang-wenang: 1.

Issue--Dapatkan instruksi berikutnya dari kepala antrian instruksi, yang

dipertahankan dalam FIFO untuk memastikan pemeliharaan aliran data yang benar. Jika ada reservation station pencocokan yang kosong, keluarkan instruksi ke stasiun dengan nilai operan, jika mereka saat ini berada dalam register. Jika tidak ada reservation station kosong, maka ada bahaya struktural dan stalls instruksi sampai stasiun atau penyangga dibebaskan. Jika operan tidak ada dalam register, perhatikan unit fungsional yang akan menghasilkan operan. Langkah ini mengganti nama register, menghilangkan bahaya WAR dan WAW. (Tahap ini kadang-kadang disebut pengiriman dalam prosesor yang dijadwalkan secara dinamis.) 2.

Execute--Jika satu atau lebih operan belum tersedia, pantau bus data biasa

sambil menunggu hasilnya dihitung. Ketika sebuah operan tersedia, ditempatkan ke dalam setiap reservation station yang menunggu hal itu. Bila semua operan tersedia, operasi dapat dijalankan pada unit fungsional yang sesuai. Dengan menunda eksekusi instruksi sampai operan tersedia, bahaya RAW dihindari. (Beberapa prosesor yang dijadwalkan secara dinamis menyebut langkah ini "masalah", namun kami menggunakan nama "execute", yang digunakan pada prosesor yang dijadwalkan secara dinamis pertama, CDC 6600.) Perhatikan bahwa beberapa instruksi bisa menjadi siap dalam siklus clock yang sama untuk unit fungsional yang sama. Meskipun unit fungsional independen dapat memulai eksekusi dalam siklus clock yang sama untuk instruksi yang berbeda, jika lebih dari satu instruksi siap untuk satu unit fungsional tunggal, unit harus memilih di antara

keduanya. Untuk reservation station floating-point, pilihan ini bisa dibuat semenamena; Loads dan penyimpanan, bagaimanapun, menghadirkan komplikasi tambahan. Loads dan penyimpanan memerlukan proses eksekusi dua langkah. Langkah  pertama menghitung alamat efektif saat register dasar tersedia, dan alamat efektifnya kemudian ditempatkan di load buffer atau penyimpanan. Loads dalam load buffer dijalankan segera setelah unit memori tersedia. Penyimpanan di st ore buffer menunggu nilai yang akan disimpan sebelum dikirim ke unit memori. Loads dan penyimpanan dipelihara dalam urutan program melalui penghitungan alamat efektif, yang akan membantu mencegah bahaya melalui memori, seperti yang akan kita lihat segera. Untuk mempertahankan perilaku pengecualian, tidak ada instruksi yang diizinkan untuk melakukan eksekusi sampai semua cabang yang mendahului instruksi dalam urutan program telah selesai. Pembatasan ini menjamin bahwa instruksi yang menyebabkan pengecualian selama eksekusi benar-benar telah dilaksanakan. Dalam sebuah prosesor yang menggunakan prediksi cabang (seperti yang dilakukan oleh  prosesor yang dijadwalkan secara dinamis), ini berarti prosesor harus mengetahui  bahwa prediksi cabang sudah benar sebelum membiarkan sebuah instruksi setelah cabang memulai eksekusi. Jika prosesor mencatat terjadinya pengecualian, namun tidak  benar-benar meningkatkannya, instruksi dapat memulai eksekusi namun tidak macet sampai ia memasukkan hasil tulis. Seperti yang akan kita lihat, spekulasi memberikan metode yang lebih fleksibel dan lebih lengkap untuk menangani pengecualian, jadi kami akan menunda pembuatan perangkat tambahan ini dan menunjukkan bagaimana spekulasi menangani masalah ini nanti. 3.

Write result - Bila hasilnya tersedia, tulis di CDB dan dari sana ke register

dan masuk ke setiap stasiun pemesanan (termasuk store buffer) menunggu hasil ini. Penyimpanan disangga di store buffer sampai nilai yang akan disimpan dan alamat  penyimpanan tersedia, kemudian hasilnya ditulis segera setelah unit memori bebas. Struktur data yang mendeteksi dan menghilangkan bahaya melekat pada reservation station, ke file register, dan ke load buffer dan store dengan informasi yang sedikit berbeda yang melekat pada objek yang berbeda. Tag ini pada dasarnya adalah nama untuk kumpulan register virtual yang digunakan untuk penggantian nama. Dalam contoh kami, bidang tag adalah kuantitas 4-bit yang menunjukkan salah satu dari lima

stasiun pemesanan atau satu dari lima load buffer. Seperti yang akan kita lihat, ini menghasilkan ekuivalen 10 register yang dapat ditunjuk sebagai register hasil (berlawanan dengan empat register doubleprecision yang berisi arsitektur 360). Dalam sebuah prosesor dengan register yang lebih nyata, kami ingin mengganti nama untuk menyediakan satu set register virtual yang lebih besar lagi. Bidang tag menjelaskan reservation station mana yang berisi instruksi yang akan menghasilkan suatu hasil yang dibutuhkan sebagai sumber operan. Begitu sebuah instruksi telah dikeluarkan dan sedang menunggu operan sumber, ini menunjuk ke operan oleh nomor reservation station dimana instruksi yang akan menulis register telah ditetapkan. Nilai yang tidak terpakai, seperti nol, menunjukkan  bahwa operan sudah tersedia di register. Karena ada lebih banyak reservation station daripada nomor register aktual, bahaya WAW dan WAR dihilangkan dengan mengganti nama hasil dengan menggunakan nomor reservation station. Meskipun dalam skema Tomasulo, reservation station digunakan sebagai register virtual yang diperluas,  pendekatan lain dapat menggunakan rangkaian register dengan register tambahan atau struktur seperti reorder buffer, yang akan kita lihat di Bagian 3.6. Dalam skema Tomasulo, dan juga metode selanjutnya yang kami lihat untuk mendukung spekulasi, hasilnya disiarkan di bus (CDB), yang dipant au oleh reservation station. Kombinasi dari bus hasil umum dan pengambilan hasil dari bus oleh reservation station menerapkan mekanisme forwarding dan bypassing yang digunakan dalam  pipeline yang dijadwalkan secara statistik. Namun, dalam melakukannya, skema yang dijadwalkan secara dinamis memperkenalkan satu siklus latensi antara sumber dan hasil, karena pencocokan hasil dan penggunaannya tidak dapat dilakukan sampai tahap Write Result. Jadi, dalam pipeline yang dijadwalkan secara dinamis, latensi efektif antara instruksi produksi dan instruksi konsumsi setidaknya satu siklus lebih lama daripada latensi unit fungsional yang menghasilkan hasilnya. Penting untuk diingat bahwa tag dalam skema Tomasulo mengacu pada buffer atau unit yang akan menghasilkan hasilnya; Nama register dibuang saat ada masalah instruksi ke reservation station. (Ini adalah perbedaan utama antara skema Tomasulo dan scoreboarding: Dalam scoreboarding, operan tetap berada dalam register dan hanya dibaca setelah instruksi produksi selesai dan instruksi konsumsi siap dijalankan.)

Setiap reservation station memiliki tujuh bidang: •

Op  operasi yang dilakukan pada sumber operan S1 dan S2.



Qj, Qk   Reservation station yang akan menghasilkan operan sumber

 – 

 – 

yang sesuai; Nilai nol menunjukkan bahwa operan sumber sudah tersedia di Vj atau Vk, atau tidak perlu. •

Vj, Vk

  The value of the source operands (Nilai operan sumber).

 – 

Perhatikan bahwa hanya satu bidang V atau bidang Q yang berlaku untuk masingmasing operan. Untuk loads, medan Vk digunakan untuk menahan bidang offset. A   Digunakan untuk menyimpan informasi untuk perhitungan alamat



 – 

memori untuk memuat atau menyimpan. Awalnya, bidang langsung instruksi disimpan di sini; Setelah penghitungan alamat, alamat efektif disimpan disini. •

Busy (Sibuk)

 Mengindikasikan bahwa reservation station ini dan unit

 — 

fungsionalnya yang menyertainya ditempati. File register memiliki field, Qi: •

Qi   Jumlah reservation stations yang berisi operasi yang hasilnya harus  – 

disimpan dalam daftar ini. Jika nilai Qi kosong (atau 0), instruksi saat ini tidak aktif menghitung hasil yang ditakdirkan untuk register ini, yang berarti bahwa nilainya hanyalah isi register. Buffer loads dan stores masing-masing memiliki field, A, yang menampung hasil dari alamat efektif setelah langkah pertama eksekusi selesai. Pada bagian selanjutnya,  pertama-tama kita akan mempertimbangkan beberapa contoh yang menunjukkan  bagaimana mekanisme ini bekerja dan kemudian memeriksa algoritma rinci.

Dynamic Scheduling: Contoh dan Algoritm

Sebelum kita membahas algoritma Tomasulo secara rinci, mari kita perhatikan  beberapa contoh yang akan membantu menggambarkan bagaimana algoritma bekerja. Contoh

Tunjukkan seperti apa tabel informasi untuk urutan kode berikut

 bila hanya loads pertama yang telah selesai dan tulis hasilnya: 1.

L.D

F6,32(R2)

2.

L.D

F2,44(R3)

3.

MUL.D

F0,F2,F4

4.

SUB.D

F8,F2,F6

5.

DIV.D

F10,F0,F6

6.

ADD.D

F6,F8,F2

Jawab Gambar 3.7 menunjukkan hasilnya dalam tiga tabel. Angka yang ditambahkan ke nama Tambah, Mult, dan Muat untuk tag untuk reservation stationsAdd1 adalah tag untuk hasil dari unit tambahan pertama. Selain itu, kami telah menyertakan tabel status instruksi. Gambar 3.7 Reservation stations dan daftar tag yang ditunjukkan saat semua instruksi dikeluarkan, namun hanya instruksi loads pertama yang telah selesai dan menuliskan hasilnya ke CDB. Loads kedua telah menyelesaikan perhitungan alamat yang efektif namun menunggu di unit memori. Kami menggunakan array Regs [] untuk merujuk ke file register dan array Mem [] untuk merujuk ke memori. Ingatlah bahwa operan ditentukan oleh field Q atau field V kapan saja. Perhatikan bahwa instruksi ADD.D, yang memiliki bahaya WAR pada tahap WB, telah dikeluarkan dan dapat diselesaikan sebelum inisiasi DIV.D Tabel ini hanya disertakan untuk membantu Anda memahami algoritma; Itu sebenarnya bukan bagian dari perangkat keras. Sebagai gantinya, reservation stations menjaga keadaan masing-masing operasi yang telah dikeluarkan. Skema Tomasulo menawarkan dua keunggulan utama dibandingkan skema sebelumnya dan yang lebih sederhana: (1) distribusi logika deteksi bahaya, dan (2)  penghapusan stalls untuk bahaya WAW dan WAR. Keuntungan pertama muncul dari reservation stations terdistribusi dan  penggunaan CDB. Jika beberapa instruksi menunggu hasil tunggal, dan setiap instruksi sudah memiliki operan yang lain, maka instruksinya dapat dilepaskan secara bersamaan oleh siaran hasil pada CDB. Jika file register terpusat digunakan, unit harus membaca hasilnya dari register saat bus register tersedia. Keuntungan kedua, penghapusan bahaya WAW dan WAR, dilakukan dengan mengganti daftar register menggunakan reservation stations dan dengan cara menyimpan operan ke reservation stations segera setelah tersedia.

Sebagai contoh, urutan kode pada Gambar 3.7 mengeluarkan DIV.D dan ADDD, meskipun ada bahaya WAR yang melibatkan F6. Bahaya dieliminasi dalam salah satu dari dua cara. Pertama, jika instruksi yang memberikan nilai untuk D IV.D telah selesai, maka Vk akan menyimpan hasilnya, yang memungkinkan DIV.D untuk mengeksekusi independen dari ADD.D (ini adalah kasus yang ditunjukkan). Di sisi lain, jika LD belum selesai, Qk akan menunjuk ke reservation stations Load1, dan instruksi DIV.D akan menjadi independen dari ADD.D. Jadi, dalam kedua kasus, ADD.D dapat mengeluarkan dan mulai mengeksekusi. Setiap penggunaan hasil DIV.D akan mengarah ke reservation stations, memungkinkan ADD.D untuk menyelesaikan dan menyimpan nilainya ke dalam register tanpa mempengaruhi DIV.D. Kita akan melihat contoh penghapusan bahaya WAW dalam waktu dekat. Tapi  pertama mari kita lihat bagaimana contoh awal kita melanjutkan eksekusi. Dalam contoh ini, dan yang berikut di bab ini, asumsikan latency berikut: load adalah 1 clock cycle, tambahkan 2 clock cycle, multiply adalah 6 clock cycle, dan divide adalah 12 clock cycle.

Contoh

Dengan menggunakan segmen kode yang sama seperti pada

contoh sebelumnya (halaman 176), tampilkan seperti apa tampilan tabel status ketika MUL.D siap untuk menulis hasilnya. Jawab Hasilnya ditunjukkan pada tiga tabel pada Gambar 3.8. Perhatikan bahwa ADD.D telah selesai sejak operan DIV.D disalin, sehingga mengatasi bahaya WAR. Perhatikan bahwa meskipun loads F6 tertunda, penambahan F6 dapat dilakukan tanpa memicu bahaya WAW.

Algoritma Tomasulo: The Details

Gambar 3.9 menentukan pemeriksaan dan langkah yang harus diikuti setiap instruksi. Seperti disebutkan sebelumnya, loads dan stores melewati unit fungsional untuk penghitungan alamat efektif sebelum melanjutkan ke independen loads atau  buffer stores. Load mengambil langkah eksekusi kedua untuk mengakses memori dan kemudian pergi menulis hasilnya untuk mengirim nilai dari memori ke file register dan

/ atau stasiun tunggu yang menunggu. Stores menyelesaikan eksekusi mereka di tahap hasil tulis, yang menuliskan hasilnya ke memori. Perhatikan bahwa semua menulis terjadi pada hasil tulis, apakah tujuannya adalah register atau memori. Pembatasan ini menyederhanakan algoritma Tomasulo dan sangat penting untuk perluasannya dengan spekulasi di Bagian 3.6.

Gambar 3.8 Kali dan bagi adalah satu-satunya petunjuk yang belum selesai.

Algoritma Tomasulo: Contoh Berbasis Loop

Untuk memahami bagaimana menghilangkan bahaya WAW dan WAR melalui  penggantian nama register secara dinamis, kita harus melihat sebuah loop. Pertimbangkan urutan sederhana berikut untuk mengalikan elemen array dengan skalar di F2: Loop: L.D

F0,0(R1)

MUL.D

F4,F0,F2

S.D

F4,0(R1)

DADDIU

R1,R1,-8

BNE

R1,R2,Loop; branches if R1¦R2

Jika kita memprediksi bahwa cabang telah diambil, dengan menggunakan reservation stations akan memungkinkan beberapa eksekusi dari loop ini dilanjutkan sekaligus. Keuntungan ini diperoleh tanpa mengubah kode

  in effect, loop dibuka

 — 

secara dinamis oleh perangkat keras yang menggunakan reservation stations yang diperoleh dengan mengganti nama untuk bertindak sebagai register tambahan.

Gambar 3.9 Langkah-langkah dalam algoritma dan apa yang dibutuhkan untuk setiap langkah. Untuk instruksi yang dikeluarkan, rd adalah tujuan, rs dan rt adalah nomor register sumber, imm adalah bidang segera yang diperpanjang, dan r adalah reservation stations atau buffer yang ditugaskan pada instruksi tersebut. RS adalah struktur data reservation stations. Nilai yang dikembalikan oleh unit FP atau oleh unit  beban disebut hasil. RegisterStat adalah status registrasi struktur data (bukan file

register, yaitu Regs []). Ketika sebuah instruksi dikeluarkan, register tujuan memiliki  bidang Qi-nya sesuai dengan jumlah buffer atau reservation stations tempat instruksi dikeluarkan. Jika operan tersedia di register, mereka akan disimpan di kolom V. Jika tidak, bidang Q ditetapkan untuk menunjukkan reservation stations yang akan menghasilkan nilai yang dibutuhkan sebagai operan sumber. Instruksi menunggu di reservation stations sampai kedua operan tersedia, ditunjukkan dengan nol di bidang Q. Bidang Q ditetapkan ke nol baik saat instruksi ini dikeluarkan atau ketika sebuah instruksi yang instruksi ini tergantung selesai dan apakah penulisannya kembali. Ketika sebuah instruksi telah selesai dieksekusi dan CDB tersedia, ia dapat melakukan  penulisan ulangnya. Semua buffer, register, dan reservation stations yang nilai Qj atau Qknya sama dengan reservation stations penyelesaian memperbarui nilainya dari CDB dan menandai bidang Q untuk menunjukkan bahwa nilai telah diterima. Dengan demikian, CDB dapat menyiarkan hasilnya ke banyak tujuan dalam satu siklus clock, dan jika instruksi tunggu memiliki operan mereka, semuanya dapat dimulai pada siklus clock berikutnya. Beban berjalan melalui dua langkah dalam eksekusi, dan stores tampil sedikit berbeda saat menulis, di mana mereka mungkin harus menunggu n ilai yang akan disimpan. Ingat bahwa, untuk melestarikan perilaku pengecualian, inst ruksi seharusnya tidak diizinkan untuk dijalankan jika cabang yang sebelumnya dalam urutan program  belum selesai. Karena setiap konsep tentang urutan program tidak dipelihara setelah tahap penerbitan, pembatasan ini biasanya dilaksanakan dengan mencegah instruksi agar tidak terjadi masalah, jika ada cabang yang tertunda yang sudah ada dalam pipa. Pada Bagian 3.6, kita akan melihat bagaimana dukungan spekulasi menghapus  pembatasan ini.

Anggap saja kita telah mengeluarkan semua instruksi dalam dua iterasi berulang dari loop, namun tidak ada floating-point load / store atau operasi yang telah selesai. Gambar 3.10 menunjukkan reservation stations, daftar tabel status, dan buffer load dan store pada saat ini. (Operasi integer ALU diabaikan, dan diasumsikan cabang diprediksi seperti yang dilakukan.) Begitu sistem mencapai keadaan ini, dua salinan loop dapat dipertahankan dengan CPI mendekati 1.0, asalkan multiplies bisa selesai dalam empat  jam. Siklus. Dengan latensi enam siklus, iterasi tambahan perlu diproses sebelum

keadaan mapan tercapai. Ini memerlukan lebih banyak reservation stations untuk menyimpan instruksi yang ada dalam eksekusi.

Gambar 3.10 Dua iterasi aktif dari loop dengan instruksi yang belum selesai. Entri di stasiun pemesanan multiplier menunjukkan bahwa muatan yang beredar adalah Seperti yang akan kita lihat nanti di bab ini, ketika diperpanjang dengan banyak  petunjuk, pendekatan Tomasulo dapat mempertahankan lebih dari satu instruksi per  jam. Sebuah load dan sebuah store dapat disimpan agar tidak terurut, asalkan mereka mengakses alamat yang berbeda. Jika sebuah load dan sebuah store mengakses alamat yang sama, maka salah satunya : •

load sebelum store dalam urutan program dan mengubah hasilnya dalam WAR

hazard, atau •

store sebelum load dalam urutan program dan mengubah hasilnya dalam RAW

hazard. Demikian pula, mengubah dua store ke alamat yang sama menghasilkan WAW hazard. Oleh karena itu, untuk menentukan apakah sebuah load dapat dieksekusi pada waktu tertentu, prosesor dapat memeriksa apakah ada store yang tidak lengkap yang mendahului load dalam urutan program berbagi alamat memori data yang sama dengan load. Demikian pula, sebuah store harus menunggu sampai tidak ada load atau store yang belum dieksekusi yang sebelumnya ada dalam urutan program dan berbagi alamat memori

data

yang

sama.

Kami

mempertimbangkan

sebuah

metode

untuk

menghilangkan pembatasan ini di Bagian 3.9. Untuk mendeteksi hazard tersebut, prosesor harus menghitung alamat memori data yang terkait dengan operasi memori sebelumnya. Sederhana, namun belum tentu optimal. Cara untuk menjamin bahwa prosesor memiliki semua alamat tersebut adalah dengan melakukan perhitungan alamat yang efektif dalam urutan program. (Kita benar benar hanya perlu menjaga agar urutan relatif antara referensi store dan referensi memori lainnya; yaitu, muatan dapat diatur ulang secara bebas.) Mari pertimbangkan situasi sebuah load terlebih dahulu. Jika kita melakukan  penghitungan alamat yang efektif dalam urutan program, maka ketika sebuah load

menyelesaikan penghitungan alamat yang efektif, kita dapat memeriksa apakah ada konflik alamat dengan memeriksa bidang A dari semua buffer store aktif. Jika alamat muat sesuai dengan alamat dari setiap entri aktif di buffer store, instruksi load tidak dikirim ke buffer load sampai store yang bentrok selesai. (Beberapa implementasi memotong nilai langsung ke load dari store yang tertunda, mengurangi penundaan untuk RAW hazard ini.) Store beroperasi dengan cara yang sama, kecuali bahwa prosesor harus memeriksa konflik di buffer load dan buffer store, karena store yang saling bertentangan tidak dapat diatur ulang sehubungan dengan muatan atau store. Pipeline yang dijadwalkan secara dinamis dapat menghasilkan kinerja yang sangat tinggi, cabang yang disediakan diprediksi secara akurat merupakan masalah yang kita hadapi pada bagian terakhir. Kelemahan utama dari pendekatan ini adalah kompleksitas skema Tomasulo, yang membutuhkan sejumlah besar perangkat keras. Secara khusus, setiap stasiun reservasi harus berisi buffer asosiatif, yang harus dijalankan pada kecepatan tinggi, serta logika kontrol yang kompleks. Performanya juga bisa dibatasi oleh CDB tunggal. Meskipun CDB tambahan dapat ditambahkan, setiap CDB harus  berinteraksi dengan masing-masing stasiun reservasi, dan perangkat pencocokan tag asosiatif harus diduplikasi di setiap stasiun untuk setiap CDB. Dalam skema Tomasulo, dua teknik yang berbeda digabungkan: penggantian nama register arsitektural ke rangkaian register yang lebih besar dan buffer dari operan sumber dari file register. Penyangga operan sumber memecahkan WAR hazard yang timbul saat operan tersedia di register. Seperti yang akan kita lihat nanti, juga memungkinkan untuk menghilangkan WAR hazard oleh penggantian nama sebuah register bersamaan dengan penyangga hasil sampai tidak ada referensi yang beredar  pada versi register sebelumnya. Pendekatan ini akan digunakan saat kita membahas spekulasi hardware. Skema Tomasulo tidak terpakai selama bertahun-tahun setelah 360/91, namun diadop si secara luas dalam beberapa masalah prosesor mulai tahun 1990an karena beberapa alasan: 1.

Meskipun algoritma Tomasulo dirancang sebelum cache, kehadiran cache,

dengan penundaan yang tidak dapat diprediksi secara inheren, telah menjadi salah satu

motivasi utama penjadwalan dinamis. Eksekusi yang tidak semestinya memungkinkan  prosesor untuk terus mengeksekusi instruksi sambil menunggu penyelesaian cache miss, sehingga menyembunyikan semua atau sebagian dari stop loss cache. 2.

Karena prosesor

menjadi lebih agresif dalam masalah dan desainer

memperhatikan penerapan kode jadwal sulit (seperti kode non-numerik), teknik seperti  penggantian nama, penjadwalan dinamis, dan spekulasi menjadi lebih penting. 3.

Hal ini dapat mencapai kinerja tinggi tanpa memerlukan compiler untuk

menargetkan kode ke struktur pipeline tertentu, sebuah properti berharga di era  perangkat lunak pasar massal yang menyusut.

3.6

Spekulasi Berbasis Hardware

Saat kita mencoba mengeksploitasi lebih banyak paralelisme tingkat i nstruksi, menjaga ketergantungan kontrol menjadi load yang meningkat. Prediksi cabang mengurangi direct stalls yang diakibatkan oleh cabang, namun untuk prosesor yang mengeksekusi  banyak instruksi per jam, cukup memprediksi cabang secara akurat mungkin tidak cukup untuk menghasilkan jumlah paralelisme tingkat instruksi yang diinginkan. Prosesor edisi yang luas mungkin perlu menjalankan cabang setiap siklus clock untuk mempertahankan performa maksimal. Oleh karena itu, pemanfaatan lebih banyak  paralelisme mengharuskan kita mengatasi keterbatasan ketergantungan kontrol. Mengatasi ketergantungan kontrol dilakukan dengan berspekulasi tentang hasil cabang dan melaksanakan program seolah-olah tebakan kita benar. Mekanisme ini mewakili  perpanjangan cabang yang halus namun penting, dibandingkan prediksi cabang dengan  penjadwalan dinamis. Secara khusus, dengan spekulasi, kita mengambil, mengeluarkan, dan melaksanakan instruksi, seolah-olah prediksi cabang kita selalu benar; Penjadwalan dinamis hanya menjemput dan mengeluarkan instruksi semacam itu. Tentu saja, kita membutuhkan mekanisme untuk menangani situasi di mana spekulasi itu tidak benar. Lampiran H membahas berbagai mekanisme untuk mendukung spekulasi oleh kompilator. Pada bagian ini, kami mengeksplorasi spekulasi perangkat keras, yang memperluas gagasan penjadwalan dinamis. Spekulasi berbasis hardware menggabungkan tiga gagasan kunci: (1) prediksi cabang dinamis untuk memilih instruksi yang akan dijalankan, (2) spekulasi untuk

memungkinkan pelaksanaan instruksi sebelum ketergantungan kontrol diselesaikan (dengan kemampuan untuk membatalkan efek dari spekulasi yang salah Urutan), dan (3) penjadwalan dinamis untuk menangani penjadwalan kombinasi blok dasar yang  berbeda. (Sebagai perbandingan, penjadwalan dinamis tanpa spekulasi hanya sebagian tumpang tindih dengan blok dasar karena memerlukan cabang diselesaikan sebelum  benar-benar menjalankan instruksi apa pun di blok dasar penerus.) Spekulasi berbasis hardware mengikuti prediksi nilai data yang harus dipilih saat melakukan instruksi eksekusi. Metode pelaksanaan program pada dasarnya adalah eksekusi aliran data: Operasi dijalankan segera setelah operan mereka tersedia. Untuk memperluas algoritma Tomasulo untuk mendukung spekulasi, kita harus memisahkan hasil bypass antara instruksi, yang diperlukan untuk melakukan instruksi secara spekulatif, dari penyelesaian instruksi yang sebenarnya. Dengan membuat  pemisahan ini, kita dapat membiarkan sebuah instruksi untuk dieksekusi dan untuk memotong hasilnya ke instruksi lain, tanpa membiarkan instruksi untuk melakukan  pembaruan yang tidak dapat dibatalkan, sampai kita tahu bahwa instruksi tersebut tidak lagi bersifat spekulatif. Menggunakan nilai bypass adalah seperti melakukan register spekulatif yang dibaca, karena kita tidak tahu apakah instruksi yang menyediakan nilai register sumber memberikan hasil yang benar sampai instruksi tidak lagi spekulatif. Bila sebuah instruksi tidak lagi bersifat spekulatif, kita membiarkannya memperbarui file register atau memori; Kita sebut langkah tambahan ini di instruksi eksekusi instruksi urutan komit. Gagasan utama di balik penerapan spekulasi adalah membiarkan petunjuk untuk melakukan kesalahan, tetapi memaksa mereka melakukan perintah secara komando dan mencegah tindakan yang tidak dapat dibatalkan (seperti memperbarui keadaan atau mengambil pengecualian) sampai sebuah instruksi dilakukan. Oleh karena itu, ketika kita menambahkan spekulasi, kita perlu memisahkan proses menyelesaikan eksekusi dari instruksi komit, karena instruksi dapat menyelesaikan eksekusi secara jauh sebelum mereka siap untuk melakukan commit. Menambahkan fase komit ini ke urutan eksekusi instruksi memerlukan satu set tambahan dari buffer perangkat keras yang menahan hasil instruksi yang telah selesai dieksekusi namun belum dilakukan. Penyangga perangkat

keras ini, yang kita sebut sebagai buffer ulang, juga digunakan untuk melewatkan hasil di antara petunjuk yang mungkin bisa dijadikan spekulasi. Register ulang (ROB) menyediakan register tambahan dengan cara yang sama seperti stasiun reservasi dalam algoritma Tomasulo memperpanjang rangkaian register. ROB memegang hasil instruksi antara waktu operasi yang terkait dengan instruksi selesai dan waktu instruksi dilakukan. Oleh karena itu, ROB adalah sumber operan untuk instruksi, seperti stasiun reservasi yang menyediakan operan dalam algoritma Tomasulo. Perbedaan utamanya adalah bahwa dalam algoritma Tomasulo, sekali instruksi menulis hasilnya, instruksi yang dikeluarkan kemudian akan menemukan hasilnya dalam file register. Dengan spekulasi, file register tidak diperbarui sampai instruk si dilakukan (dan kita tahu secara definitif bahwa instruksi harus dijalankan); Dengan demikian,  persediaan ROB beroperasi dalam interval antara penyelesaian eksekusi instruksi dan instruksi komit. ROB mirip dengan buffer store dalam algoritma Tomasulo, dan kami mengintegrasikan fungsi buffer store ke dalam ROB untuk kesederhanaan. Register ulang (ROB) menyediakan register tambahan dengan cara yang sama seperti stasiun reservasi dalam algoritma Tomasulo memperpanjang rangkaian register. ROB memegang hasil instruksi antara waktu operasi yang terkait dengan instruksi selesai dan waktu instruksi dilakukan. Oleh karena itu, ROB adalah sumber operan untuk instruksi, seperti stasiun reservasi yang menyediakan operan dalam algoritma Tomasulo. Perbedaan utamanya adalah bahwa dalam algoritma Tomasulo, sekali instruksi menulis hasilnya, instruksi yang dikeluarkan kemudian akan menemukan hasilnya dalam file register. Dengan spekulasi, file register tidak diperbarui sampai instruk si dilakukan (dan kita tahu secara definitif bahwa instruksi harus dijalankan); Dengan demikian,  persediaan ROB beroperasi dalam interval antara penyelesaian eksekusi instruksi dan instruksi komit. ROB mirip dengan buffer store dalam algoritma Tomasulo, dan kami mengintegrasikan fungsi buffer store ke dalam ROB untuk kesederhanaan. Setiap entri di ROB berisi empat bidang: jenis instruksi, bidang tujuan, bidang nilai, dan bidang siap. Bidang tipe instruksi menunjukkan apakah instruksi tersebut adalah cabang (dan tidak memiliki hasil tujuan), sebuah store (yang memiliki alamat memori tujuan), atau operasi register (operasi ALU atau load, yang memiliki tujuan mendaftar). Bidang tujuan memasok nomor register (untuk operasi load dan ALU) atau alamat

memori (untuk store) di mana hasil instruksi harus ditulis. Bidang ni lai digunakan untuk menahan nilai hasil instruksi sampai instruksi dilakukan. Kita akan melihat contoh entri ROB dalam waktu dekat. Akhirnya, field siap menunjukkan bahwa instruksi telah selesai dieksekusi, dan nilainya sudah siap.

Gambar 3.11 Struktur dasar unit FP menggunakan algoritma Tomasulo dan diperluas untuk menangani spekulasi. Membandingkan ini dengan Gambar 3.6 di halaman 173, yang menerapkan algoritma Tomasulo, perubahan utamanya adalah penambahan ROB dan penghapusan buffer store, yang fungsinya diintegrasikan ke dalam ROB. Mekanisme ini dapat diperluas ke beberapa masalah dengan membuat CDB lebih lebar untuk memungkinkan beberapa penyelesaian per jam. Gambar 3.11 menunjukkan struktur perangkat keras prosesor termasuk ROB. ROB menggabungkan buffer store. Strores masih mengeksekusi dalam dua langkah, namun langkah kedua dilakukan dengan instruksi komit. Meskipun fungsi penggantian dari stasiun reservasi digantikan oleh ROB, kita masih memerlukan tempat untuk operasi penyangga (dan operan) antara waktu yang mereka keluarkan dan saat mereka memulai eksekusi. Fungsi ini masih disediakan oleh stasiun reservasi. Karena setiap instruksi memiliki posisi di ROB sampai ia melakukan, kami memberi tag hasil dengan menggunakan nomor entri ROB daripada menggunakan nomor stasiun reservasi. Penandaan ini mengharuskan agar ROB ditugaskan untuk instruksi harus dilacak di stasiun reservasi. Kemudian di bagian ini, kita akan mengeksplorasi sebuah implementasi alternatif yang menggunakan register ekstra untuk penggantian nama dan antrian yang menggantikan ROB untuk menentukan kapan instruksi dapat dilakukan. Berikut adalah empat langkah yang terlibat dalam eksekusi instruksi: 1.

Menerbitkan - Dapatkan instruksi dari antrian instruksi. Terbitkan instruksi jika

ada stasiun reservasi kosong dan slot kosong di ROB; Kirim operan ke stasiun reservasi  jika tersedia di register atau ROB. Perbarui entri kontrol untuk menunjukkan bahwa  penyangga sedang digunakan. Jumlah entri ROB yang dialokasikan untuk hasilnya juga dikirim ke stasiun reservasi, sehingga jumlahnya bisa digunakan untuk menandai hasilnya saat ditempatkan di CDB. Jika semua pemesanan sudah penuh atau ROB su dah  penuh, maka masalah instruksi terhenti sampai ada entri yang tersedia.

2.

Jalankan - Jika satu atau lebih operan belum tersedia, pantau CDB sambil

menunggu register dihitung. Langkah ini memeriksa RAW hazard. Bila kedua operan tersedia di stasiun reservasi, jalankan operasi. Instruksi mungkin memerlukan banyak siklus clock pada tahap ini, dan load masih memerlukan dua langkah pada tahap ini. Store hanya perlu memiliki base register yang tersedia pada lan gkah ini, karena eksekusi untuk store pada saat ini hanyalah penghitungan alamat yang efektif. 3.

Tulis hasilnya - Bila hasilnya tersedia, tulis di CDB (dengan tag ROB dikirim

saat instruksi dikeluarkan) dan dari CDB ke dalam ROB, serta ke setiap stasiun  pemesanan yang menunggu hasil ini. Tandai stasiun reservasi tersedia. Tindakan khusus diperlukan untuk instruksi store. Jika nilai yang akan disimpan tersedia, maka dituliskan ke dalam field Value dari entri ROB untuk store. Jika nilai yang akan disimpan tidak tersedia, CDB harus dipantau sampai nilai tersebut disiarkan, pada saat mana bidang  Nilai entri ROB store diperbarui. Untuk kesederhanaan, kita berasumsi bahwa ini terjadi selama tahap penulisan hasil sebuah store; Kita bahas santai persyaratan ini nanti. 4.

Komit - Ini adalah tahap akhir menyelesaikan sebuah instruksi, setelah itu hanya

hasilnya saja. (Beberapa prosesor menyebut fase komit ini "selesai" atau "kelulusan.") Ada tiga urutan tindakan yang berbeda pada komit bergantung pada apakah instruksi komit adalah cabang dengan prediksi, store, atau instruksi lain yang salah (normal melakukan). Kasus komit normal terjadi saat sebuah instruksi mencapai kepala ROB dan hasilnya ada dalam buffer; Pada saat ini, prosesor memperbarui register dengan hasilnya dan menghapus instruksi dari ROB. Melakukan sebuah store serupa kecuali memori yang diperbarui bukan hasil register. Bila cabang dengan prediksi yang salah mencapai kepala ROB, ini menunjukkan bahwa spekulasi itu salah. ROB memerah dan eksekusi diulang kembali pada penerus cabang yang benar. Jika cabang diprediksi dengan benar, cabangnya sudah selesai. Setelah instruksi dilakukan, masuknya ROB direklamasi dan register atau tujuan memori diperbarui, sehingga menghilangkan kebutuhan akan entri ROB. Jika ROB terisi, kami berhenti mengeluarkan instruksi sampai entri dibuat gratis. Sekarang, mari kita periksa bagaimana skema ini akan bekerja dengan contoh yang sama seperti yang kita gunakan untuk algoritma Tomasulo. CONTOH :

Asumsikan latensi yang sama untuk unit fungsional floating-point seperti pada contoh sebelumnya: tambahkan 2 siklus clock, kalikan adalah 6 siklus clock, dan bagi 12 siklus clock. Dengan menggunakan segmen kode di bawah ini, yang sama dengan yang kita gunakan untuk menghasilkan Gambar 3.8, menunjukkan seperti apa tampilan tabel status ketika MUL.D siap untuk komit.

JAWAB : Gambar 3.12 menunjukkan hasilnya pada tiga tabel. Perhatikan bahwa meskipun instruksi SUB.D telah menyelesaikan eksekusi, tidak dilakukan sampai MUL.D melakukan. Stasiun reservasi dan field register status berisi informasi dasar yang sama dengan algoritma Tomasulo (lihat halaman 176 untuk deskripsi bidang-bidang tersebut). Perbedaannya adalah bahwa nomor stasiun reservasi diganti dengan nomor entri ROB di bidang Qj dan Qk, dan juga di kolom status pendaftaran, dan kami telah menambahkan kolom Dest ke stasiun reservasi. Bidang Dest menunjuk entri ROB yang merupakan tujuan untuk hasil yang dihasilkan oleh entri stasiun reservasi ini.

Contoh di atas menggambarkan perbedaan penting antara prosesor dengan spekulasi dan prosesor dengan penjadwalan dinamis. Bandingkan isi Gambar 3.12 dengan gambar 3.8 di halaman 179, yang menunjukkan urutan kode yang sama dalam operasi pada prosesor dengan algoritma Tomasulo. Perbedaan utamanya adalah bahwa,  pada contoh di atas, tidak ada instruksi setelah instruksi awal yang tidak selesai (MUL.D di atas) diperbolehkan untuk diselesaikan. Sebaliknya, pada Gambar 3.8, instruksi SUB.D dan ADD.D juga telah selesai. Mengeksekusi kode secara dinamis sambil mempertahankan model interupsi yang tepat. Misalnya, jika instruksi MUL.D menyebabkan interupsi, kita bisa menunggu sampai mencapai kepala ROB dan mengambil interupsi, membilas instruksi tertunda lainnya dari ROB. Karena instruksi commit terjadi secara berurutan, ini menghasilkan pengecualian yang tepat.

Gambar 3.12 Pada saat MUL.D siap untuk melakukan, hanya dua instruksi L.D telah dilakukan, walaupun beberapa lainnya telah menyelesaikan eksekusi. MUL.D berada di kepala ROB, dan dua instruksi L.D hanya ada untuk memudahkan pemahaman. Instruksi SUB.D dan ADD.D tidak akan dilakukan sampai instruksi MUL.D dilakukan, walaupun petunjuknya tersedia dan dapat digunakan sebagai sumber untuk instruksi lainnya. DIV.D sedang dalam eksekusi, namun belum selesai semata-mata karena latensinya yang lebih lama dari MUL.D. Kolom Nilai menunjukkan nilai yang dipegang; Format #X digunakan untuk merujuk pada bidang nilai entri ROB X. Susun ulang buffer 1 dan 2 benar-benar selesai namun ditampilkan untuk tujuan informasi. Kami tidak menunjukkan entri untuk antrian load / store, namun entri ini disimpan secara berurutan. Beberapa pengguna dan arsitek telah memutuskan bahwa pengecualian floating-point yang tidak tepat dapat diterima pada prosesor berkinerja tinggi, karena program ini kemungkinan akan dihentikan; Lihat Lampiran J untuk diskusi lebih lanjut mengenai topik ini. Jenis pengecualian lainnya, seperti kesalahan halaman, jauh lebih sulit untuk mengakomodasi jika tidak tepat, karena program harus melanjutkan eksekusi secara transparan setelah menangani pengecualian semacam itu. Penggunaan ROB dengan perintah instruksi in-order memberikan pengecualian yang tepat, selain mendukung eksekusi spekulatif, seperti ditunjukkan contoh berikut. CONTOH : Perhatikan contoh kode yang digunakan sebelumnya untuk algoritma Tomasulo dan ditunjukkan pada Gambar 3.10 dalam eksekusi:

Asumsikan bahwa kita telah mengeluarkan semua instruksi dalam loop dua kali. Mari kita juga berasumsi bahwa L.D dan MUL.D dari iterasi pertama telah dilakukan dan semua instruksi lainnya telah menyelesaikan eksekusi. Biasanya, store akan menunggu di ROB untuk kedua operan alamat efektif (R1 dalam contoh ini) dan nilainya (F4 dalam contoh ini). Karena kita hanya mempertimbangkan jalur floating-point, asumsikan alamat efektif untuk store dihitung pada saat instruksi dikeluarkan. JAWAB : Gambar 3.13 menunjukkan hasilnya dalam dua tabel.

Gambar 3.13 Hanya instruksi L.D dan MUL.D yang telah dilakukan, walaupun semua lainnya telah menyelesaikan eksekusi. Makanya, tidak ada stasiun reservasi yang sibuk dan tidak ada isshown. Instruksi yang tersisa akan dilakukan secepat mungkin. Dua rombongan ulang pertama buffer kosong, namun ditampilkan untuk kelengkapan. Karena baik nilai register maupun nilai memori sebenarnya tidak ditulis sampai instruksi dilakukan, prosesor dapat dengan mudah membatalkan tindakan spekulati fnya saat cabang ditemukan salah paham. Misalkan cabang BNE tidak diambil pertama kalinya pada Gambar 3.13. Instruksi sebelum cabang hanya akan dilakukan saat masing-masing mencapai kepala ROB; Saat cabang mencapai kepala penyangga itu,  buffer hanya dibersihkan dan prosesor mulai mengambil instruksi dari jalur lain. Dalam prakteknya, prosesor yang berspekulasi mencoba pulih sedini mungkin setelah cabang salah paham. Pemulihan ini dapat dilakukan dengan membersihkan ROB untuk semua entri yang muncul setelah cabang yang salah pilih, sehingga memungkinkan sebelum cabang di ROB melanjutkan, dan memulai kembali  pengambilan pada penerus cabang yang benar. Pada prosesor spekulatif, kinerja lebih sensitif terhadap prediksi cabang, karena dampak misprediksinya akan lebih tinggi. Dengan demikian, semua aspek penanganan cabang - akurasi prediksi, latensi deteksi misprediksia, dan waktu pemulihan misprediks semakin penting. Pengecualian ditangani dengan tidak mengenali pengecualian sampai siap melakukan komit. Jika instruksi berspekulasi menimbulkan pengecualian, pengecualian dicatat dalam ROB. Jika terjadi salah alamat cabang dan instruksi seharusnya tidak dieksekusi, pengecualian disiram bersamaan dengan instruksi saat ROB dibersihkan. Jika instruksi mencapai kepala ROB, maka kita tahu itu tidak lagi spekulatif dan  pengecualian harus benar-benar diambil. Kita juga dapat mencoba untuk mengatasi  pengecualian begitu muncul dan semua cabang terdahulu teratasi, namun ini lebih menantang dalam hal pengecualian daripada mispredict cabang dan, karena hal itu terjadi lebih jarang, tidak begitu penting. Gambar 3.14 menunjukkan langkah-langkah eksekusi untuk sebuah instruksi, serta kemudian kondisi yang harus dipuaskan untuk melanjutkan ke langkah dan tindakan

yang dilakukan. Kami menunjukkan kasus di mana cabang yang salah kaprah tidak terselesaikan sampai komit. Meskipun spekulasi tampak seperti tambahan sederhana untuk penjadwalan dinamis, perbandingan Gambar 3.14 dengan angka yang sebanding untuk algoritma Tomasulo pada Gambar 3.9 menunjukkan bahwa spekulasi menambah komplikasi yang signifikan pada kontrol. Selain itu, ingatlah bahwa misprediksi cabang agak rumit juga. Ada perbedaan penting dalam bagaimana store ditangani dalam prosesor spekulatif dibandingkan dengan algoritma Tomasulo. Dalam algoritma Tomasulo, sebuah store dapat memperbarui memori saat mencapai hasil tulis (yang memastikan bahwa alamat efektif telah dihitung) dan nilai data yang disimpan tersedia. Dalam prosesor spekulatif, store memperbarui memori hanya saat mencapai kepala ROB. Perbedaan ini memastikan memori tidak diperbarui sampai sebuah instruksi tidak lagi spekulatif. Gambar 3.14 memiliki satu penyederhanaan yang signifikan untuk store, yang tidak dibutuhkan dalam praktik. Gambar 3.14 membutuhkan store untuk menunggu di tahap hasil tulis untuk operan sumber register yang nilainya akan disimpan; Nilainya kemudian dipindahkan dari kolom Vk dari stasiun reservasi store ke field Value dari entri ROB milik store. Pada kenyataannya, bagaimanapun, nilai yang harus disimpan tidak perlu sampai sebelum store melakukan dan dapat ditempatkan langsung ke entri ROB store dengan instruksi sumber. Hal ini dilakukan dengan memilik i jalur perangkat keras saat nilai sumber yang akan disimpan tersedia di entri ROB store dan mencari ROB pada setiap instruksi yang ada untuk mencari store dependen.

Gambar 3.14 Langkah-langkah dalam algoritma dan apa yang dibutuhkan untuk setiap langkah. Untuk instruksi penerbitan, rd adalah tujuan, rs dan rt adalah sumbernya, yang merupakan stasiun reservasi yang dialokasikan, b adalah entri ROB yang ditugaskan, dan h adalah kepala masuk ROB. RS adalah struktur data stasiun reservasi. Nilai yang dikembalikan oleh stasiun reservasi disebut hasilnya. RegisterStat adalah register struktur data, Regs mewakili register sebenarnya, dan ROB adalah struktur data buffer  penyangga ulang.

Penambahan ini tidak rumit, namun menambahkannya memiliki dua efek: Kita  perlu menambahkan field ke ROB, dan Gambar 3.14, yang sudah dalam huruf kecil, akan lebih lama lagi! Meskipun Gambar 3.14 membuat penyederhanaan ini, dalam contoh kita, kita akan membiarkan toko melewati tahap hasil tuli s dan hanya menunggu nilainya siap saat ia melakukan. Seperti algoritma Tomasulo, kita harus menghindari hazard melalui ingatan. WA W dan WAR hazard melalui memori dieliminasi dengan spekulasi karena pembaruan aktual memori terjadi secara berurutan, ketika sebuah toko berada di kepala ROB, dan karena itu, tidak ada beban atau toko sebelumnya yang masih dapat ditunda. RAW hazard melalui ingatan dijaga oleh dua batasan: 1.

Tidak mengizinkan sebuah beban untuk memulai langkah kedua pelaksanaannya

 jika ada entri ROB aktif yang ditempati oleh sebuah toko memiliki bidang Tujuan yang sesuai dengan nilai bidang A dari muatan. 2.

Mempertahankan urutan program untuk perhitungan alamat efektif dari sebuah

muatan sehubungan dengan semua toko sebelumnya. Bersama-sama, kedua batasan ini memastikan bahwa setiap muatan yang mengakses lokasi memori yang ditulis oleh toko sebelumnya tidak dapat melakukan akses memori sampai toko tersebut menulis data. Beberapa prosesor spekulatif benar-benar akan memotong nilai dari toko ke beban secara langsung, bila terjadi RAW hazard. Pendekatan lain adalah memprediksi potensi tabrakan dengan menggunakan bentuk  prediksi nilai; Kita mempertimbangkan hal ini di Bagian 3.9. Meskipun penjelasan tentang eksekusi spekulatif ini berfokus pada floating point, teknik ini dengan mudah diperluas ke register integer dan unit fungsional. Memang spekulasi mungkin lebih bermanfaat dalam program integer, karena program semacam itu cenderung memiliki kode dimana perilaku cabang kurang dapat diprediksi. Selain itu, teknik ini dapat diperluas untuk bekerja dalam prosesor multi-masalah dengan mengizinkan banyak instruksi untuk mengeluarkan dan melakukan setiap jam. Sebenarnya, spekulasi mungkin paling menarik dalam prosesor semacam itu, karena teknik yang kurang ambisius mungkin bisa memanfaatkan ILP yang cukup dalam blok dasar saat dibantu oleh kompilator. 3.7

Pemanfaatan ILP Menggunakan Beberapa Masalah dan Penjadwalan Statis

Teknik dari bagian sebelumnya dapat digunakan untuk menghilangkan data, mengendalikan warung, dan mencapai CPI ideal satu. Untuk meningkatkan kinerja, kami ingin mengurangi CPI menjadi kurang dari satu, namun CPI tidak dapat dikurangi di bawah satu jika kami hanya mengeluarkan satu instruksi setiap siklus clock. Tujuan dari prosesor multi-isu, yang dibahas dalam beberapa bagian berikutnya, adalah memungkinkan beberapa petunjuk untuk diterbitkan dalam siklus clock. Prosesor berganda hadir dalam tiga rasa utama: 1.

Prosesor superscalar yang dijadwalkan secara statistik

2.

VLIW (sangat panjang kata instruksi) prosesor

3.

Prosesor superscalar yang dijadwalkan secara dinamis

Dua jenis prosesor superscalar mengeluarkan sejumlah instruksi per jam yang berbeda beda dan menggunakan eksekusi dalam urutan jika mereka melakukan eksekusi statis atau out-of-order jika dijadwalkan secara dinamis. Prosesor VLIW, sebaliknya, mengeluarkan sejumlah instruksi yang tetap yang diformat  baik sebagai satu instruksi besar atau sebagai paket instruksi tetap dengan paralelisme di antara instruksi yang secara eksplisit ditunjukkan oleh instruksi. Prosesor VLIW secara inheren dijadwalkan oleh kompilator. Ketika Intel dan HP menciptakan arsitektur IA-64, yang dijelaskan di Appendix H, mereka juga memperkenalkan nama EPIC --secara eksplisit instruksi paralel komputer-- untuk gaya arsitektur ini. Meskipun superscalars yang dijadwalkan secara statik mengeluarkan sejumlah instruksi  per jam yang bervariasi daripada sejumlah instruksi per jam, mereka sebenarnya lebih dekat dalam konsep VLIW, karena kedua pendekatan bergantung pada compiler untuk menjadwalkan kode untuk prosesor. Karena berkurangnya keuntungan dari superscalar yang dijadwalkan secara statik saat lebar isu meningkat, superscalars yang dijadwalkan secara statik digunakan terutama untuk lebar isu sempit, biasanya hanya dua instruksi. Di luar lebar itu, sebagian besar perancang memilih untuk menerapkan VLIW atau superscalar yang dijadwalkan secara dinamis. Karena kesamaan hardware dan teknologi compiler yang dibutuhkan, kami fokus pada VLIWs di bagian ini. Wawasan dari bagian ini mudah diekstrapolasikan ke superscalar yang dijadwalkan secara statistik. Gambar 3.15 merangkum pendekatan dasar untuk beberapa masalah dan karakteristik  pembeda mereka dan menunjukkan prosesor yang menggunakan setiap pendekatan.

Pendekatan Dasar VLIW VLIW menggunakan beberapa unit fungsional independen. Alih-alih mencoba mengeluarkan beberapa instruksi independen ke unit, paket VLIW beberapa operasi menjadi satu instruksi yang sangat panjang, atau mengharuskan instruksi dalam paket masalah memenuhi batasan yang sama. Karena tidak ada perbedaan mendasar dalam dua pendekatan tersebut, kita hanya akan mengasumsikan bahwa beberapa operasi ditempatkan dalam satu instruksi, seperti pada pendekatan VLIW yang asli. Karena keuntungan VLIW meningkat seiring tingkat kenaikan harga maksimum, kitai fokus pada prosesor edisi yang lebih luas. Memang, untuk prosesor dua isu sederhana, overhead superscalar mungkin minimal. Banyak perancang mungkin berpendapat  bahwa prosesor empat masalah memiliki overhead yang dapat diatur, namun seperti yang akan kita lihat nanti di bab ini, pertumbuhan overhead adalah faktor utama yang membatasi prosesor edisi yang lebih luas.

Gambar 3.15 Kelima pendekatan utama yang digunakan untuk prosesor multi-isu dan karakteristik utama yang membedakannya. Bab ini berfokus pada teknik intensif  perangkat keras, yang semuanya merupakan bentuk superscalar. Lampiran H berfokus  pada pendekatan berbasis compiler. Pendekatan EPIC, sebagaimana terkandung dalam arsitektur IA-64, memperluas banyak konsep pendekatan VLIW awal, memberikan  perpaduan antara pendekatan statis dan dinamis.

Mari kita pertimbangkan sebuah prosesor VLIW dengan instruksi yang mengandung lima operasi, termasuk satu operasi bilangan bulat (yang juga bisa berupa cabang), dua operasi floating-point, dan dua referensi memori. Instruksi akan memiliki satu set  bidang untuk setiap unit fungsional - mungkin 16 sampai 24 bit per unit, menghasilkan  panjang instruksi antara 80 dan 120 bit. Sebagai perbandingan, Intel Itanium 1 dan 2  berisi enam operasi per paket instruksi (yaitu, mereka membiarkan masalah bersamaan dari dua paket instruksi tiga, seperti yang dijelaskan oleh Lampiran H). Agar unit fungsional tetap sibuk, harus ada cukup paralelisme dalam urutan kode untuk mengisi slot operasi yang tersedia. Paralelisme ini ditemukan dengan membuka

gulungan dan menjadwalkan kode dalam satu lingkaran yang lebih besar. Jika gulungan gulungan menghasilkan kode garis lurus, maka teknik penjadwalan lokal, yang  beroperasi pada satu blok dasar tunggal, dapat digunakan. Jika menemukan dan mengeksploitasi paralelisme memerlukan kode penjadwalan lintas cabang, algoritma  penjadwalan global yang jauh lebih kompleks harus digunakan. Algoritma penjadwalan global tidak hanya lebih kompleks dalam struktur, tapi juga harus menghadapi  pengekangan optimasi yang jauh lebih rumit, karena kode bergerak melintasi cabang mahal. Pada Lampiran H, kita akan membahas penjadwalan jejak, salah satu teknik  penjadwalan global yang dikembangkan secara khusus untuk VLIW; Kami juga akan mengeksplorasi dukungan perangkat keras khusus yang memungkinkan beberapa cabang bersyarat untuk dieliminasi, memperluas kegunaan penjadwalan lokal dan meningkatkan kinerja penjadwalan global. Untuk saat ini, kita akan bergantung pada loop unrolling untuk menghasilkan rangkaian kode garis lurus yang panjang, sehingga kita dapat menggunakan penjadwalan lokal untuk membangun instruksi VLIW dan fokus pada seberapa baik prosesor ini  beroperasi. CONTOH : Misalkan kita memiliki VLIW yang bisa mengeluarkan dua referensi memori, dua operasi FP, dan satu operasi bilangan bulat atau cabang di setiap siklus clock. Tunjukkan versi unrolled loop x [i] = x [i] + s (lihat halaman 158 untuk kode MIPS) untuk prosesor semacam itu. Latih sebanyak mungkin untuk menghilangkan warung. Abaikan cabang yang tertunda. JAWAB

:

Gambar 3.16 menunjukkan kode. Loop telah dibuka untuk membuat tujuh salinan dari tubuh, yang menghilangkan semua kios (yaitu, siklus isi yang benar-benar kosong), dan  berjalan dalam 9 siklus. Kode ini menghasilkan tingkat lari tujuh hasil dalam 9 siklus, atau 1,29 siklus per hasil, hampir dua kali lebih cepat dari superscalar dua masalah dari Bagian 3.2 yang menggunakan kode yang tidak dibuka dan terjadwal. Untuk model VLIW yang asli, ada masalah teknis dan logistik yang membuat  pendekatan ini kurang efisien. Masalah teknisnya adalah meningkatnya ukuran kode

dan keterbatasan operasi lockstep. Dua elemen yang berbeda digabungkan untuk meningkatkan ukuran kode secara substansial untuk VLIW. Pertama, menghasilkan operasi yang cukup dalam fragmen kode garis lurus memerlukan loop gulungan yang ambisius (seperti pada contoh sebelumnya), sehingga meningkatkan ukuran kode. Kedua, setiap kali instruksi tidak penuh, unit fungsional yang tidak digunakan menerjemahkan ke bit terbuang dalam pengkodean instruksi. Pada Lampiran H, kami memeriksa pendekatan penjadwalan perangkat lunak, seperti pipelining perangkat lunak, yang dapat mencapai keuntungan dari pembongkaran tanpa banyak perluasan kode.

Gambar 3.16 instruksi VLIW yang menempati loop bagian dalam dan mengganti urutan yang tidak tergulung. Kode ini mengambil 9 siklus dengan asumsi tidak ada penundaan cabang; Biasanya penundaan cabang juga perlu dijadwalkan. Tingkat masalah adalah 23 operasi dalam 9 siklus clock, atau 2,5 operasi per siklus. Efisiensi, persentase slot yang tersedia yang berisi operasi, sekitar 60%. Untuk mencapai tingkat masalah ini, dibutuhkan jumlah register MIPS yang lebih besar yang biasanya digunakan dalam lingkaran ini. Urutan kode VLIW di atas memerlukan setidaknya delapan register FP, sedangkan urutan kode yang sama untuk prosesor MIPS dasar dapat digunakan sebagai  beberapa register astwo FP atau sebanyak lima saat dibuka dan dijadwalkan. VLIW awal dioperasikan di lockstep; Tidak ada perangkat keras deteksi bahaya sama sekali. Struktur ini menentukan bahwa sebuah kios di setiap pipa unit fungsional harus menyebabkan seluruh prosesor mogok, karena semua unit fungsional harus terus disinkronkan. Meskipun kompilator mungkin dapat menjadwalkan unit fungsional deterministik untuk mencegah kios, memprediksi akses data mana yang akan menemukan kios cache dan penjadwalannya sangat sulit. Oleh karena itu, cache perlu diblokir dan menyebabkan semua unit fungsional macet. Karena tingkat penerbitan dan  jumlah referensi memori menjadi besar, pembatasan sinkronisasi ini menjadi tidak dapat diterima. Pada prosesor yang lebih baru, unit fungsional beroperasi lebih independen, dan compiler digunakan untuk menghindari bahaya pada saat masalah, sementara pemeriksaan perangkat keras memungkinkan eksekusi yang tidak sinkron setelah instruksi dikeluarkan.

Kompatibilitas kode biner juga merupakan masalah logistik utama untuk VLIW. Dalam  pendekatan VLIW yang ketat, urutan kode menggunakan kedua definisi set instruksi dan struktur pipa terperinci, termasuk unit fungsional dan latensi mereka. Dengan demikian, jumlah unit fungsional dan unit latency yang berbeda memerlukan versi kode yang berbeda. Persyaratan ini membuat migrasi antara implementasi berturut-turut , atau antara implementasi dengan lebar isu yang berbeda, lebih sulit daripada desain superscalar. Tentu saja, mendapatkan peningkatan kinerja dari desain superscalar baru mungkin memerlukan kompilasi ulang. Meskipun demikian, kemampuan untuk menjalankan file biner lama adalah keuntungan praktis untuk pendekatan superscalar. Pendekatan EPIC, dimana arsitektur IA-64 adalah contoh utama, memberikan solusi untuk banyak masalah yang dihadapi pada desain VLIW awal, termasuk perluasan spekulasi dan metode perangkat lunak yang lebih agresif untuk mengatasi keterbatasan ketergantungan perangkat keras sambil menjaga kompatibilitas biner. Tantangan utama bagi semua prosesor multi masalah adalah mencoba mengeksploitasi sejumlah besar ILP. Ketika paralelisme berasal dari unrolling loop sederhana dalam  program FP, loop asli mungkin bisa berjalan efisien pada prosesor vektor (dijelaskan di  bab berikutnya). Tidak jelas bahwa prosesor multi-isu lebih disukai daripada prosesor vektor untuk aplikasi semacam itu; Biayanya sama, dan prosesor vektor biasanya kecepatannya sama atau lebih cepat. Keuntungan potensial dari prosesor multi-isu versus prosesor vektor adalah kemampuan mereka untuk mengekstrak beberapa  paralelisme dari kode yang kurang terstruktur dan kemampuan mereka untuk dengan mudah menyimpan semua bentuk data. Untuk alasan ini, beberapa pendekatan masalah menjadi metode utama untuk mengambil keuntungan dari paralelisme tingkat i nstruksi, dan vektor terutama menjadi perpanjangan pada prosesor ini. 3.8

Pemanfaatan ILP Menggunakan Dynamic Scheduling, Multiple Issue, dan

Spekulasi Sejauh ini, kita telah melihat bagaimana mekanisme individual penjadwalan dinamis, multiple issue, dan spekulasi bekerja. Pada bagian ini, kita menempatkan ketiganya  bersama-sama, yang menghasilkan mikroarsitektur yang sangat mirip dengan mikroprosesor modern. Untuk kesederhanaan, kami hanya mempertimbangkan tingkat

masalah dua instruksi per jam, namun konsepnya tidak berbeda dengan prosesor modern yang mengeluarkan tiga atau lebih instruksi per jam. Mari kita asumsikan kita ingin memperpanjang algoritma Tomasulo untuk mendukung  banyak masalah superscalar pipeline dengan unit integer, load / store, dan floating-point yang terpisah (keduanya FP multiply dan FP add), yang masing-masing dapat memulai operasi pada setiap jam. Kami tidak ingin mengeluarkan instruksi ke stasiun reservasi yang rusak, karena ini bisa menyebabkan pelanggaran terhadap program semantik. Untuk mendapatkan keuntungan penuh dari penjadwalan dinamis, kami akan membiarkan pipa tersebut menghasilkan kombinasi dua instruksi dalam satu jam, dengan menggunakan perangkat keras penjadwalan untuk benar-benar menetapkan operasi ke unit bilangan bulat dan floating-point. Karena interaksi instruksi integer dan floating-point sangat penting, kami juga memperpanjang skema Tomasulo untuk menangani unit dan register bilangan bulat dan floating-point, serta menggabungkan eksekusi spekulatif. Seperti ditunjukkan Gambar 3.17, organisasi dasar serupa dengan  prosesor dengan spekulasi dengan satu isu per jam, kecuali bahwa logika penyelesaian masalah dan penyelesaian harus ditingkatkan agar beberapa instruksi diproses per jam. Menerbitkan beberapa petunjuk per jam dalam prosesor yang dijadwalkan secara dinamis (dengan atau tanpa spekulasi) sangat kompleks karena alasan sederhana mengapa beberapa instruksi mungkin saling bergantung satu sama lain. Karena ini, tabel harus diperbarui untuk petunjuk secara paralel; Jika tidak, tabel akan salah atau ketergantungannya mungkin hilang. Dua pendekatan yang berbeda telah digunakan untuk mengeluarkan beberapa instruksi  per jam dalam prosesor yang dijadwalkan secara dinamis, dan keduanya bergantung  pada pengamatan bahwa kuncinya adalah menetapkan stasiun reservasi dan memperbarui tabel kontrol pipa. Salah satu pendekatannya adalah menjalankan langkah ini dalam setengah siklus clock, sehingga dua instruksi dapat diproses dalam satu siklus clock; Pendekatan ini tidak mudah diperluas untuk menangani empat instruksi per jam. Alternatif kedua adalah membangun logika Alternatif kedua adalah membangun logika yang diperlukan untuk menangani dua instruksi atau lebih sekaligus, termasuk kemungkinan ketergantungan antara instruksi. Prosesor superscalar modern yang mengeluarkan empat atau lebih instruksi per jam

mungkin mencakup kedua pendekatan: Mereka menggabungkan pipa dan memperlebar logika masalah. Pengamatan kunci adalah bahwa kita tidak bisa begitu saja menyingkirkan masalah ini. Dengan membuat berbagai instruksi mengambil banyak  jam karena instruksi baru mengeluarkan setiap siklus clock, kita harus dapat menetapkan stasiun reservasi dan untuk memperbarui tabel pipa, sehingga instruksi dependen yang dikeluarkan pada jam berikutnya dapat menggunakan informasi terbaru. Langkah masalah ini adalah salah satu hambatan paling mendasar dalam superskalar yang dijadwalkan secara dinamis. Untuk menggambarkan kompleksitas proses ini, Gambar 3.18 menunjukkan logika masalah untuk satu kasus: mengeluarkan sebuah  beban diikuti oleh operasi FP yang bergantung. Logika didasarkan pada gambar 3.14 di halaman 191, namun hanya mewakili satu kasus. Dalam superscalar modern, setiap kemungkinan kombinasi instruksi dependen yang diizinkan untuk diterbitkan dalam siklus clock yang sama harus dipertimbangkan. Karena jumlah kemungkinan naik sebagai kuadrat dari jumlah instruksi yang dapat dikeluarkan dalam satu jam, langkah masalah adalah kemacetan yang mungkin terjadi untuk upaya melampaui empat instruksi per jam.

Gambar 3.17 Organisasi dasar dari beberapa prosesor dengan spekulasi. Dalam kasus ini, organisasi dapat mengizinkan FP berkembang biak, FP menambahkan, memasukkan, dan memuat / menyimpan semua masalah secara bersamaan (dengan asumsi satu masalah per jam per unit fungsional). Perhatikan bahwa beberapa datapath harus diperlebar untuk mendukung banyak masalah: CDB, bus operan, dan logika logika instruksi, yang tidak ditunjukkan dalam gambar ini. Yang terakhir adalah masalah yang sulit, seperti yang kita diskusikan dalam teks. Kita dapat menggeneralisasi detail Gambar 3.18 untuk menggambarkan strategi dasar untuk memperbarui logika masalah dan tabel reservasi dalam superscalar yang dijadwalkan secara dinamis dengan sampai n masalah per jam sebagai berikut: 1.

Tetapkan stasiun reservasi dan penyangga ulang untuk setiap instruksi yang

mungkin dikeluarkan dalam bundel edisi berikutnya. Tugas ini dapat dilakukan sebel um

 jenis instruksi diketahui, dengan hanya mengatur ulang entri buffer ulang secara  berurutan ke instruksi dalam paket menggunakan n entri buffer ulang yang ada dan dengan memastikan bahwa cukup stasiun reservasi tersedia untuk mengeluarkan keseluruhan bundel, terlepas dari apa itu mengandung. Dengan membatasi jumlah instruksi dari kelas yang diberikan (katakanlah, satu FP, satu bilangan bulat, satu beban, satu toko), stasiun reservasi yang diperlukan dapat dialokasikan terlebih dahulu. Jika stasiun reservasi yang memadai tidak tersedia (seperti saat beberapa instruksi berikut dalam program ini adalah satu jenis instruksi), bundelnya rusak, dan hanya sebagian instruksi, dalam urutan program asli, dikeluarkan. Sisa instruksi dalam bundel dapat ditempatkan dalam bundel berikutnya untuk masalah potensial. 2.

Analisis semua dependensi di antara instruksi dalam bundel masalah.

3.

Jika instruksi dalam bundel tergantung pada instruksi sebelumnya dalam bundel,

gunakan nomor buffer pemesanan ulang yang ditugaskan untuk memperbarui tabel reservasi untuk instruksi dependen. Jika tidak, gunakan tabel reservasi yang ada dan susun ulang informasi penyangga untuk memperbarui entri tabel reservasi untuk instruksi penerbitan. Tentu saja, apa yang membuat di atas sangat rumit adalah bahwa semuanya dilakukan secara paralel dalam satu siklus clock!

Gambar 3.18 Langkah-langkah masalah untuk sepasang instruksi dependen (disebut 1 dan 2) di mana instruksi 1 adalah beban FP dan instruksi 2 adalah operasi FP yang operan pertamanya adalah hasil instruksi beban; R1 dan r2 adalah stasiun reservasi yang ditugaskan untuk instruksi; Dan b1 dan b2 adalah entri buffer reorder yang ditugaskan. Untuk instruksi penerbitan, rd1 dan rd2 adalah tujuan; Rs1, rs2, dan rt2 adalah sumbernya (muatan hanya memiliki satu sumber); R1 dan r2 adalah stasiun reservasi yang dialokasikan; Dan b1 dan b2 adalah entri ROB yang ditugaskan. RS adalah struktur data stasiun reservasi. RegisterStat adalah register struktur data, Regs mewakili register sebenarnya, dan ROB adalah struktur data buffer penyangga ulang. Perhatikan  bahwa kita perlu menetapkan ulang entri buffer untuk logika ini agar beroperasi dengan  benar dan ingat bahwa semua pembaruan ini terjadi dalam satu siklus clock secara  paralel, tidak berurutan!

Pada bagian belakang pipa, kita harus bisa menyelesaikan dan melakukan banyak instruksi per jam. Langkah-langkah ini agak lebih mudah daripada masalah karena  beberapa petunjuk yang benar-benar dapat dilakukan dalam siklus clock yang sama  pasti sudah ditangani dan diselesaikan dengan segala ketergantungan. Seperti yang akan kita lihat, para perancang telah menemukan cara menangani kompleksitas ini: Intel i7, yang kita periksa di Bagian 3.13, pada dasarnya menggunakan skema yang telah kita gambarkan untuk beberapa isu spekulatif, termasuk sejumlah besar stasiun reservasi,  penyangga ulang, Dan buffer beban dan toko yang juga digunakan untuk menangani cache nonblocking. Dari sudut pandang kinerja, kita dapat menunjukkan bagaimana konsep tersebut sesuai dengan sebuah contoh. CONTOH : Pertimbangkan eksekusi dari loop berikut, yang menambahkan setiap elemen dari array integer, pada prosesor dua isu, sekali tanpa spekulasi dan sekali dengan spekulasi:

Asumsikan bahwa ada unit fungsional integer yang terpisah untuk penghitungan alamat efektif, untuk operasi ALU, dan untuk evaluasi kondisi cabang. Buat tabel untuk tiga iterasi pertama loop ini untuk kedua prosesor. Asumsikan bahwa sampai dua instruksi dari jenis apapun dapat dilakukan per jam. JAWAB : Angka 3.19 dan 3.20 menunjukkan kinerja prosesor dua dimensi yang dijadwalkan secara dinamis, tanpa dan dengan spekulasi. Dalam hal ini, dimana cabang bisa menjadi  pembatas kinerja kritis, spekulasi membantu secara signifikan. Cabang ketiga dalam  prosesor spekulatif dijalankan pada siklus clock 13, sementara dijalankan pada siklus clock 19 pada pipa nonspekulatif. Karena tingkat penyelesaian pada pipa non-spekulatif tertinggal di belakang tingkat suku bunga dengan cepat, pipa nonspekulatif akan macet ketika beberapa pengulangan dikeluarkan. Kinerja prosesor nonspekulatif dapat ditingkatkan dengan membiarkan instruksi beban untuk menyelesaikan penghitungan alamat efektif sebelum cabang diputuskan, namun jika akses memori spekulatif diperbolehkan, perbaikan ini hanya akan mendapatkan 1 jam per iterasi.

Contoh ini dengan jelas menunjukkan bagaimana spekulasi dapat menguntungkan bila ada cabang yang bergantung pada data, yang jika tidak akan membatasi kinerja. Keuntungan ini bergantung pada prediksi cabang yang akurat. Spekulasi yang salah tidak memperbaiki kinerja; Sebenarnya, ini biasanya merugikan kinerja dan, seperti yang akan kita lihat, secara dramatis menurunkan efisiensi energi.

Gambar 3.19 Waktu penerbitan, eksekusi, dan penulisan menghasilkan versi dual-link dari pipa kami tanpa spekulasi. Perhatikan bahwa LD yang mengikuti BNE tidak bisa memulai eksekusi lebih awal karena harus menunggu sampai hasil cabang ditentukan. Jenis program ini, dengan cabang data-dependent yang tidak bisa diatasi lebih awal, menunjukkan kekuatan spekulasi. Unit fungsional terpisah untuk penghitungan alamat, operasi ALU, dan evaluasi kondisi cabang memungkinkan beberapa instruksi dijalankan dalam siklus yang sama. Gambar 3.20 menunjukkan contoh ini dengan spekulasi.

Gambar 3.20 Waktu penerbitan, eksekusi, dan hasil penulisan untuk edisi dual-isu pipa kami dengan spekulasi. Perhatikan bahwa LD yang mengikuti BNE bisa memulai eksekusi lebih awal karena bersifat spekulatif. 3.9

Teknik Lanjutan untuk Pengiriman Instruksi dan Spekulasi

Dalam jaringan dengan kinerja tinggi, terutama yang memiliki banyak masalah, memprediksi cabang dengan baik tidak cukup; Kita sebenarnya harus bisa memberikan aliran instruksi bandwidth tinggi. Dalam beberapa prosesor edisi terbaru, ini berarti memberikan 4 sampai 8 instruksi setiap siklus clock. Kami melihat metode untuk meningkatkan bandwidth pengiriman instruksi terlebih dahulu. Kami kemudian beralih ke serangkaian isu utama dalam menerapkan teknik spekulasi maju, termasuk  penggunaan daftar nama berganda versus pemesanan ulang buffer, agresivitas spekulasi, dan teknik yang disebut prediksi nilai, yang mencoba memprediksi hasil  perhitungan dan yang selanjutnya dapat berlanjut. Meningkatkan ILP Meningkatkan Instruction Fetch Bandwidth

Prosesor multi-masalah akan mengharuskan jumlah instruksi rata-rata yang diambil setiap siklus clock setidaknya sebesar rata-rata throughput. Tentu saja, mengambil instruksi ini membutuhkan jalur yang cukup lebar ke cache instruksi, na mun aspek yang  paling sulit adalah menangani cabang. Pada bagian ini, kita melihat dua metode untuk menangani

cabang

dan

kemudian

membahas

bagaimana

prosesor

modern

mengintegrasikan prediksi instruksi dan fungsi prefetch. Penyangga Target Cabang Untuk mengurangi hukuman cabang untuk pipa lima tahap sederhana kami, dan juga untuk jalur pipa yang lebih dalam, kita harus tahu apakah instruksi yang belum direkayasa adalah cabang dan, jika ya, apa yang seharusnya dilakukan oleh program  program berikutnya (PC). Jika instruksi adalah cabang dan kita tahu apa PC berikutnya seharusnya, kita bisa memiliki hukuman cabang nol. Cache prediksi-cabang yang menyimpan alamat prediksi untuk instruksi berikutnya setelah cabang disebut buffer target cabang atau cache target cabang. Gambar 3.21 menunjukkan penyangga target cabang. Karena buffer target cabang memprediksi alamat instruksi berikutnya dan akan mengirimkannya sebelum mendekodekan instruksi, kita harus tahu apakah instruksi yang diambil dianggap sebagai cabang yang diambil. Jika PC instruksi yang diambil sesuai dengan alamat di buffer prediksi, PC prediksi yang sesuai akan digunakan sebagai PC berikutnya. Perangkat keras untuk buffer target cabang ini pada dasarnya identik dengan perangkat keras untuk cache.

Gambar 3.21 Sebuah buffer target cabang. PC dari instruksi yang diambil cocok dengan satu set alamat instruksi yang tersimpan di kolom pertama; Ini mewakili alamat cabang yang dikenal. Jika PC cocok dengan salah satu entri ini, maka instruksi yang diambil adalah cabang yang diambil, dan bidang kedua, prediksi PC, berisi prediksi untuk PC  berikutnya setelah cabang tersebut. Mengambil segera dimulai di alamat itu. Bidang ketiga, yang bersifat opsional, dapat digunakan untuk prediksi bit negara. Jika entri yang cocok ditemukan di buffer target cabang, pengambilan dimulai segera  pada PC yang diprediksi. Perhatikan bahwa tidak seperti buffer prediksi cabang, entri  prediktif harus disesuaikan dengan instruksi ini karena PC yang diprediksi akan dikirim

sebelum diketahui apakah instruksi ini bahkan merupakan cabang. Jika prosesor tidak memeriksa apakah entri tersebut cocok dengan PC ini, maka PC yang salah akan dikirim keluar untuk instruksi yang bukan cabang, sehingga menghasilkan kinerja yang lebih  buruk. Kita hanya perlu menyimpan cabang yang diprediksi-diprediksi di buffer target cabang, karena cabang yang tidak dilepas hanya perlu mengambil instruksi sekuensial  berikutnya, seolah-olah itu bukan cabang.

Gambar 3.22 Langkah-langkah yang terlibat dalam menangani instruksi dengan  penyangga target cabang.

Gambar 3.23 Hukuman untuk semua kemungkinan kombinasi apakah cabang berada dalam buffer dan apa yang sebenarnya terjadi, dengan asumsi kita menyimpan hanya cabang yang diambil di buffer. Tidak ada hukuman cabang jika semuanya diprediksi dengan benar dan cabangnya ditemukan di buffer target. Jika cabang tidak diprediksi dengan benar, hukumannya sama dengan satu siklus clock untuk memperbarui buffer dengan informasi yang benar (di mana instruksi tidak dapat diambil) dan satu siklus clock, jika perlu, untuk memulai kembali pengambilan instruksi yang benar berikutnya untuk cabang. Jika cabang tidak ditemukan dan diambil, hukuman dua siklus dijumpai, selama waktu buffer diperbarui.

Gambar 3.22 menunjukkan langkah-langkah saat menggunakan penyangga target cabang untuk pipa lima tahap sederhana. Dari gambar ini kita bisa melihat bahwa tidak akan ada delay cabang jika entri prediksi cabang ditemukan di buffer dan prediksi sudah  benar. Jika tidak, akan ada hukuman minimal dua siklus clock. Berurusan dengan mispredictions dan misses adalah tantangan yang signifikan, karena kita biasanya harus menghentikan instruksi yang diambil saat kita menulis ulang entri buffer. Dengan demikian, kami ingin membuat proses ini cepat untuk meminimalkan hukuman. Untuk mengevaluasi seberapa baik penyangga target cabang, pertama-tama kita harus menentukan hukuman dalam semua kasus yang mungkin terjadi. Gambar 3.23 berisi informasi ini untuk pipa lima tahap sederhana. CONTOH :

Tentukan total hukuman cabang untuk penyangga target cabang dengan asumsi siklus  penalti untuk kesalahan penilaian individu dari Gambar 3.23. Buat asumsi berikut tentang akurasi prediksi dan hit rate: •

Prediksi akurasi adalah 90% (untuk petunjuk dalam buffer).



Hit rate dalam buffer adalah 90% (untuk cabang diprediksi diambil).

JAWAB : Kami menghitung hukuman dengan melihat probabilitas dua kejadian: cabang diprediksi diambil namun akhirnya tidak diambil, dan cabang diambil namun tidak ditemukan di buffer. Keduanya membawa hukuman dua siklus.

Hukuman ini dibandingkan dengan hukuman cabang cabang yang tertunda, yang kami evaluasi di Lampiran C, sekitar 0,5 jam siklus per cabang. Ingat, meskipun, bahwa  perbaikan dari prediksi cabang dinamis akan tumbuh seiring dengan panjang pipa dan, karenanya, penundaan cabang tumbuh; Selain itu, prediktor yang lebih baik akan menghasilkan keuntungan kinerja yang lebih besar. Prosesor berkinerja tinggi modern memiliki penundaan misprediks cabang sesuai urutan 15 siklus clock; Jelas, prediksi yang akurat sangat penting! Satu variasi pada buffer target cabang adalah menyimpan satu atau lebih  petunjuk target alih-alih, atau sebagai tambahan, target target yang diprediksi. Variasi ini memiliki dua keunggulan potensial. Pertama, memungkinkan akses buffer cabangtarget untuk memakan waktu lebih lama dari waktu antara pengambilan instruksi  berturut-turut, yang memungkinkan penyangga target cabang yang lebih besar. Kedua,  penyangga instruksi target sebenarnya memungkinkan kita melakukan optimasi yang disebut branch folding. Cabang lipat dapat digunakan untuk mendapatkan cabang tanpa syarat 0 siklus dan terkadang cabang bersyarat 0-siklus. Pertimbangkan penyangga target cabang yang memberi instruksi buffer dari jalur yang diprediksi dan diakses dengan alamat cabang tanpa syarat. Satu-satunya fungsi cabang tanpa syarat adalah mengubah PC. Jadi, ketika penyangga target cabang memberi sinyal  pukulan dan mengindikasikan bahwa cabang tidak bersyarat, pipa hanya dapat mengganti instruksi dari penyangga target cabang menggantikan instruksi yang dikembalikan dari tembolok (yang merupakan cabang tak bersyarat) . Jika prosesor

mengeluarkan beberapa instruksi per siklus, maka buffer perlu menyediakan beberapa instruksi untuk mendapatkan keuntungan maksimal. Dalam beberapa kasus, mungkin saja untuk menghilangkan biaya cabang bersyarat. Prediktor Kembali Alamat Ketika kita mencoba untuk meningkatkan kesempatan dan keakuratan spekulasi kita menghadapi tantangan untuk memprediksi lompatan tidak langsung, yaitu melompat yang alamat tujuannya bervariasi pada saat runtime. Meskipun program bahasa tingkat tinggi akan menghasilkan lompatan seperti itu untuk panggi lan prosedur tidak langsung,  pernyataan pilih atau kasus, dan gotos yang dihitung oleh FORTRAN, sebagian besar lompatan tidak langsung berasal dari pengembalian prosedur. Sebagai contoh, untuk  benchmark SPEC95, prosedur mengembalikan lebih dari 15% cabang dan sebagian  besar lompatan tidak langsung rata-rata. Untuk bahasa berorientasi obyek seperti C ++ dan Java, pengembalian prosedur bahkan lebih sering. Dengan demikian, fokus pada  pengembalian prosedur tampaknya tepat. Meskipun pengembalian prosedur dapat diprediksi dengan penyangga target cabang, keakuratan teknik prediksi semacam itu bisa rendah jika prosedur dipanggil dari  beberapa situs dan panggilan dari satu situs tidak berkerumun pada waktunya. Misalnya, di SPEC CPU95, prediktor cabang yang agresif mencapai akurasi kurang dari 60% untuk cabang kembali tersebut. Untuk mengatasi masalah ini, beberapa desain menggunakan penyangga kecil alamat pengirim yang berfungsi sebagai stack. Struktur ini menyimpan alamat pengembalian terakhir: mendorong alamat pengirim di tumpukan saat ada panggilan dan muncul satu saat kembali. Jika temboloknya cukup  besar (yaitu, sama besar dengan kedalaman panggilan maksimum), ini akan memprediksi pengembaliannya dengan sempurna. Gambar 3.24 menunjukkan kinerja seperti buffer kembali dengan 0 sampai 16 elemen untuk sejumlah benchmark SPEC CPU95. Kami akan menggunakan prediktor return yang sama ketika kita memeriksa studi ILP di Bagian 3.10. Baik prosesor Intel Core dan prosesor AMD Phenom memiliki  prediksi alamat pengirim.

Gambar 3.24 Prediksi akurasi untuk buffer alamat pengirim dioperasikan sebagai tumpukan pada sejumlah benchmark SPEC CPU95. Akurasi adalah fraksi dari alamat

 pengirim yang diprediksi dengan benar. Penyangga 0 entri menyiratkan bahwa prediksi cabang standar digunakan. Karena kedalaman panggilan biasanya tidak besar, dengan  beberapa pengecualian, penyangga sederhana bekerja dengan baik. Data ini berasal dari Skadron dkk. [1999] dan gunakan mekanisme fix-up untuk mencegah korupsi dari alamat pengirim yang di-cache. Unit Ambil Instruksi Terpadu Untuk memenuhi tuntutan beberapa prosesor, banyak perancang baru-baru ini telah memilih untuk menerapkan unit pengambilan instruksi terpadu sebagai unit otonom terpisah yang memberi umpan instruksi ke keseluruhan jaringan pipa. Intinya, ini berarti mengenali bahwa mengambil instruksi karakter sebagai tahap pipa tunggal yang sederhana mengingat kompleksitas beberapa masalah tidak lagi valid. 1.

Prediksi cabang terpadu - Prediktor cabang menjadi bagian dari unit

 pengambilan instruksi dan terus-menerus meramalkan cabang, sehingga mendorong  pipa pengambilan. 2.

Instruksi

prefetch-Untuk

memberikan banyak instruksi

per jam, unit

 pengambilan instruksi kemungkinan akan perlu diambil di depan. Unit secara mandiri mengatur pembuatan instruksi (lihat Bab 2 untuk diskusi teknik untuk melakukan ini), mengintegrasikannya dengan prediksi cabang. 3.

Akses memori instruksi dan penyangga-Saat mengambil beberapa instruksi per

siklus, berbagai kompleksitas ditemukan, termasuk kesulitan untuk mengambil  beberapa instruksi mungkin memerlukan akses beberapa baris cache. Unit pengambilan instruksi mengenkapsulasi kompleksitas ini, menggunakan prefetch untuk mencoba menyembunyikan biaya penyeberangan blok-blok cache. Unit pengambilan instruksi  juga menyediakan penyangga, pada dasarnya bertindak sebagai unit on-demand untuk memberikan instruksi kepada tahap penerbitan sesuai kebutuhan dan dalam jumlah yang dibutuhkan. Hampir semua prosesor high-end sekarang menggunakan unit pengambilan instruksi terpisah yang terhubung ke sisa pipa oleh penyangga yang berisi instruksi yang tertunda. Spekulasi: Isu Implementasi dan Ekstensi Pada bagian ini kita mengeksplorasi empat isu yang melibatkan perancangan trade-off dalam spekulasi, dimulai dengan penggunaan penggantian nama register, pendekatan

yang sering digunakan sebagai pengganti buffer ulang. Kami kemudian membahas satu kemungkinan kemungkinan perluasan spekulasi pada arus kontrol: sebuah gagasan yang disebut prediksi nilai. Dukungan Spekulasi: Daftar Mengganti Nama Berganda versus Reorder Buffer Salah satu alternatif penggunaan buffer reorder (ROB) adalah penggunaan eksplisit rangkaian fisik yang lebih besar yang dikombinasikan dengan penggantian nama register. Pendekatan ini didasarkan pada konsep penggantian nama yang digunakan dalam algoritma Tomasulo dan memperluasnya. Dalam algoritma Tomasulo, nilai-nilai dari register yang terlihat secara arsitektural (R0, ..., R31 dan F0, ..., F31) terkandung,  pada setiap titik dalam eksekusi, dalam beberapa kombinasi dari rangkaian register dan stasiun reservasi. Dengan penambahan spekulasi, nilai register juga dapat sementara  berada di ROB. Dalam kedua kasus, jika prosesor tidak mengeluarkan instruksi baru untuk jangka waktu tertentu, semua instruksi yang ada akan dilakukan, dan nilai register akan muncul dalam file register, yang secara langsung berhubungan dengan register yang terlihat secara arsitektural. Dalam pendekatan register-renaming, rangkaian register fisik yang diperluas digunakan untuk menampung register arsitektural dan nilai sementara. Jadi, register diperpanjang menggantikan sebagian besar fungsi ROB dan stasiun reservasi; Hanya antrian untuk memastikan bahwa instruksi lengkap dalam rangka sangat dibutuhkan. Selama masalah instruksi, proses penggantian nama memetakan nama register arsitektur ke nomor register fisik dalam rangkaian register yang diperluas, mengalokasikan register baru yang tidak terpakai untuk tujuan. Wawasan WAW dan WAR dihindari dengan mengganti nama daftar tujuan, dan pemulihan spekulasi ditangani karena register fisik yang memegang tujuan instruksi tidak menjadi register arsitektural sampai instruksi dilakukan. Peta penggantian nama adalah struktur data sederhana yang memasok nomor register fisik register yang saat ini sesuai dengan daftar arsitektur yang ditentukan, sebuah fungsi yang dilakukan oleh tabel status register dalam algoritma Tomasulo. Ketika sebuah instruksi melakukan, tabel penggantian nama diperbarui secara  permanen untuk menunjukkan bahwa daftar fisik sesuai dengan daftar arsitektur aktual, sehingga secara efektif menyelesaikan pembaruan ke status prosesor. Meskipun ROB

tidak perlu mendaftar ulang nama, perangkat keras harus tetap melacak instruksi dalam struktur seperti antrian dan memperbarui tabel penggantian nama secara ketat. Keuntungan dari pendekatan penggantian nama versus pendekatan ROB adalah bahwa instruksi komit sedikit disederhanakan, karena hanya memerlukan dua tindakan sederhana: (1) mencatat bahwa pemetaan antara nomor register arsitektural dan nomor register fisik tidak lagi bersifat spekulatif, dan (2 ) Membebaskan semua register fisik yang digunakan untuk menyimpan nilai "tua" dari daftar arsitektur. Dalam sebuah rancangan dengan stasiun reservasi, sebuah stasiun dibebaskan saat instruksi yang menggunakannya selesai, dan entri ROB dibebaskan saat instruksi yang sesuai dilakukan. Dengan mendaftar ulang nama, register deallocating lebih kompleks, karena sebelum kita membebaskan daftar fisik, kita harus tahu bahwa itu tidak lagi sesuai dengan daft ar arsitektur dan tidak ada lagi penggunaan register fisik yang luar biasa. Daftar fisik sesuai dengan daftar arsitektur sampai daftar arsitektur ditulis ulang, sehingga tabel  penggantian nama mengarah ke tempat lain. Artinya, jika tidak ada penggantian nama entri ke register fisik tertentu, maka tidak lagi sesuai dengan daftar arsitektur. Mungkin masih ada penggunaan register fisik yang beredar. Prosesor dapat menentukan apakah ini adalah kasus dengan memeriksa daftar sumber yang berisi petunjuk dari semua instruksi dalam antrian unit fungsional. Jika register fisik yang diberikan tidak muncul sebagai sumber dan tidak ditunjuk sebagai register arsitektural , mungkin reklamasi dan  penginstalan ulang. Sebagai alternatif, prosesor hanya bisa menunggu sampai instruksi lain yang menulis register arsitektur yang sama. Pada saat itu, tidak ada lagi penggunaan nilai yang lebih tua yang beredar. Meskipun metode ini mungkin mengikat sebuah register fisik sedikit lebih lama dari yang diperlukan, namun mudah diterapkan dan digunakan pada superskkalasi terbaru. Satu pertanyaan yang mungkin Anda tanyakan adalah bagaimana kit a bisa tahu register mana yang merupakan register arsitektural jika mereka terus berubah? Sebagian besar waktu ketika program dijalankan, tidak masalah. Ada kasus yang jelas, bagaimanapun, di mana proses lain, seperti sistem operasi, harus dapat mengetahui dengan pasti di mana isi daftar arsitektur tertentu berada. Untuk memahami bagaimana kemampuan ini

disediakan, anggap prosesor tidak mengeluarkan instruksi untuk beberapa periode waktu tertentu. Akhirnya semua instruksi dalam pipa akan dilakukan, dan pemetaan antara register yang terlihat secara arsitektural dan register fisik akan menjadi stabil. Pada saat itu, subset dari register fisik berisi register yang terlihat secara arsitektural, dan nilai dari setiap register fisik yang tidak terkait dengan register arsitektur tidak dibutuhkan. Kemudian mudah untuk memindahkan register arsitektur ke subset fisik register tetap sehingga nilainya dapat dikomunikasikan ke proses lain. Kedua register mengubah nama dan menyusun ulang buffer terus digunakan pada  prosesor high-end, yang sekarang memiliki kemampuan untuk memiliki instruksi sebanyak 40 atau 50 (termasuk beban dan toko yang menunggu di cache) dalam  penerbangan. Entah penggantian nama atau penyangga ulang digunakan, hambatan kompleksitas utama untuk superscalar jadwal dinamis tetap mengeluarkan kumpulan instruksi dengan ketergantungan di dalam bundel. Secara khusus, instruksi dependen dalam bundel masalah harus dikeluarkan dengan register virtual yang ditetapkan dari instruksi yang mereka andalkan. Sebuah strategi untuk masalah instruksi dengan  penggantian nama register yang serupa dengan yang digunakan untuk multiple issue dengan perataan ulang buffer (lihat halaman 198) dapat digunakan, sebagai berikut: 1.

Masalah logika mencatat cukup banyak register fisik untuk keseluruhan bundel

(katakanlah, empat register untuk bundel empat instruksi dengan paling banyak satu hasil register per instruksi). 2.

Logika masalah menentukan ketergantungan apa yang ada di dalam bundel. Jika

ketergantungan tidak ada dalam bundel, struktur rename register digunakan untuk menentukan register fisik yang dipegang, atau akan dipegang, hasil dimana instruksi tergantung. Bila tidak ada ketergantungan yang ada di dalam bundel hasilnya adalah dari bundel edisi sebelumnya, dan tabel penggantian nama akan memiliki nomor register yang benar. 3.

Logika masalah menentukan ketergantungan apa yang ada di dalam bundel. Jika

ketergantungan tidak ada dalam bundel, struktur rename register digunakan untuk menentukan register fisik yang dipegang, atau akan dipegang, hasil dimana instruksi tergantung. Bila tidak ada ketergantungan yang ada di dalam bundel hasilnya adalah

dari bundel edisi sebelumnya, dan tabel penggantian nama akan memiliki nomor register yang benar. Perhatikan bahwa seperti pada kasus buffer reorder, logika masalah harus menentukan dependensi dalam bundel dan memperbarui tabel nama ulang dalam satu jam, dan, seperti sebelumnya, kompleksitas melakukan hal ini untuk sejumlah besar instruksi per  jam menjadi Keterbatasan utama dalam isu tersebut. Berapa banyak untuk berspekulasi Salah satu keuntungan spekulasi yang signifikan adalah kemampuannya untuk mengungkap kejadian yang seharusnya menghentikan arus pipa lebih awal, seperti cache misses. Keuntungan potensial ini, bagaimanapun, hadir dengan potensi kerugian yang signifikan. Spekulasi tidak gratis. Butuh waktu dan energi, dan pemulihan spekulasi yang salah akan mengurangi kinerja. Selain itu, untuk mendukung tingkat eksekusi instruksi yang lebih tinggi yang dibutuhkan untuk mendapatkan keuntungan dari spekulasi, prosesor harus memiliki sumber daya tambahan, yang mengambil area dan kekuatan silikon. Akhirnya, jika spekulasi menyebabkan kejadian luar biasa terjadi, seperti cache atau translation lookaside buffer (TLB) hilang, potensi kenaikan kinerja yang signifikan akan meningkat, jika kejadian itu tidak terjadi tanpa spekulasi. Untuk mempertahankan sebagian besar keuntungan, sambil meminimalkan kerugian, kebanyakan jaringan pipa dengan spekulasi hanya akan memungkinkan kejadian luar biasa berbiaya rendah (seperti cache tingkat pertama) untuk ditangani dalam mode spekulatif. Jika kejadian luar biasa mahal terjadi, seperti kehilangan cache tingkat kedua atau miss TLB, prosesor akan menunggu sampai instruksi yang menyebabkan kejadian tidak lagi spekulatif sebelum menangani acara. Meskipun hal ini mungkin sedikit menurunkan kinerja beberapa program, namun hal ini menghindari kerugian kinerja yang signifikan pada orang lain, terutama yang menderita frekuensi kejadian yang tinggi ditambah dengan prediksi cabang yang kurang bagus. Pada 1990-an, potensi kerugian spekulasi kurang jelas. Seiring deng an berkembangnya  prosesor, biaya spekulasi sebenarnya semakin nyata, dan keterbatasan isu dan spekulasi yang lebih luas telah terlihat jelas. Kami segera kembali ke masalah ini. Berspekulasi melalui beberapa cabang

Dalam contoh yang telah kita bahas di bab ini, adalah mungkin untuk menyelesaikan sebuah cabang sebelum harus berspekulasi mengenai hal yang lain. Tiga situasi yang  berbeda dapat diuntungkan dari berspekulasi pada beberapa cabang secara bersamaan: (1) frekuensi cabang yang sangat tinggi, (2) clustering cabang yang signifikan, dan (3)  penundaan yang lama pada unit fungsional. Dalam dua kasus pertama, mencapai kinerja tinggi dapat berarti bahwa banyak cabang berspekulasi, dan bahkan mungkin berarti menangani lebih dari satu cabang per jam. Program database, dan perhitungan integer lainnya yang kurang terstruktur, sering menunjukkan sifat-sifat ini, membuat spekulasi  pada beberapa cabang penting. Demikian juga, penundaan panjang dalam unit fungsional dapat meningkatkan pentingnya berspekulasi di banyak cabang sebagai cara untuk menghindari kios-kios dari penundaan perpindahan pipa yang lebih lama. Berspekulasi pada beberapa cabang sedikit memperumit proses pemulihan spekulasi namun langsung terjadi sebaliknya. Pada tahun 2011, tidak ada prosesor yang menggabungkan spekulasi penuh dengan menyelesaikan beberapa cabang per siklus, dan tidak mungkin biaya untuk melakukannya dapat dibenarkan dalam hal kinerja versus kompleksitas dan kekuatan. Spekulasi dan Tantangan Efisiensi Energi Apa dampak spekulasi terhadap efisiensi energi? Sepintas lalu, orang mungkin  berpendapat bahwa menggunakan spekulasi selalu mengurangi efisiensi energi, karena kapan pun spekulasi salah, ia mengkonsumsi kelebihan energi dalam dua cara : 1.

Instruksi yang berspekulasi dan yang hasilnya tidak dibutuhkan menghasilkan

kelebihan kerja untuk prosesor, membuang energi. 2.

Membatalkan

spekulasi

dan

mengembalikan

keadaan

prosesor

untuk

melanjutkan eksekusi pada alamat yang sesuai mengkonsumsi energi tambahan yang tidak dibutuhkan tanpa spekulasi. Tentu, spekulasi akan menaikkan konsumsi daya dan, jika kita bisa mengendalikan spekulasi, kemungkinan untuk mengukur biaya (atau setidaknya biaya daya dinamis). Tapi, jika spekulasi menurunkan waktu eksekusi lebih banyak daripada meningkatkan konsumsi daya rata-rata, maka total energi yang dikonsumsi mungkin kurang.

Gambar 3.25 Fraksi instruksi yang dieksekusi sebagai akibat dari misspeculation  biasanya jauh lebih tinggi untuk program integer (lima pertama) versus program KB (lima terakhir). Dengan demikian, untuk memahami dampak spekulasi pada efisiensi energi, kita perlu melihat seberapa sering spekulasi mengarah ke pekerjaan yang tidak perlu. Jika sejumlah instruksi yang tidak dibutuhkan dilakukan, kemungkinan spekulasi akan memperbaiki waktu berjalan dengan jumlah yang sebanding! Gambar 3.25 menunjukkan fraksi instruksi yang dieksekusi dari misspeculation. Seperti yang bisa kita lihat, fraksi ini kecil dalam kode ilmiah dan signifikan (sekitar 30% rata-rata) dalam kode bilangan bulat. Dengan demikian, tidak mungkin spekulasi itu hemat energi untuk aplikasi bilangan bulat. Perancang bisa menghindari spekulasi, mencoba untuk mengurangi kesalahan pandang, atau memikirkan pendekatan baru, seperti hanya  berspekulasi pada cabang yang diketahui sangat mudah ditebak. Prediksi nilai Salah satu teknik untuk meningkatkan jumlah ILP yang tersedia dalam sebuah program adalah prediksi nilai. Prediksi nilai mencoba memprediksi nilai yang akan dihasilkan oleh sebuah instruksi. Jelas, karena kebanyakan instruksi menghasilkan nilai yang  berbeda setiap kali dijalankan (atau setidaknya memiliki nilai yang berbeda dari seperangkat nilai), prediksi nilai hanya memiliki kesuksesan terbatas. Akan tetapi, ada  beberapa petunjuk yang lebih mudah untuk memprediksi nilai yang dihasilkanmisalnya, beban yang keluar dari kolam konstan atau yang memuat nilai yang jarang  berubah. Sebagai tambahan, ketika sebuah instruksi menghasilkan nilai yang dipilih dari sejumlah kecil nilai potensial, kemungkinan untuk memprediksi nilai yang dihasilkan dengan mengkorelasikannya dengan perilaku program lainnya. Prediksi nilai berguna jika meningkatkan jumlah ILP secara signifikan. Kemungkinan ini kemungkinan besar terjadi ketika sebuah nilai digunakan sebagai sumber rangkaian  perhitungan dependen, seperti sebuah beban. Karena prediksi nilai digunakan untuk meningkatkan spekulasi dan spekulasi yang salah memiliki dampak kinerja yang merugikan, keakuratan prediksi sangat penting. Meskipun banyak peneliti telah berfokus pada prediksi nilai dalam sepuluh tahun terakhir, hasilnya tidak pernah cukup menarik untuk dibenarkan dalam penggabungan

nyata. Sebagai gantinya, ide yang lebih sederhana dan lebih tua, terkait dengan prediksi nilai, telah digunakan: prediksi aliasing alamat. Alamat aliasing prediction adalah teknik sederhana yang memprediksi apakah dua toko atau beban dan toko mengacu  pada alamat memori yang sama. Jika dua referensi tersebut tidak merujuk ke alamat yang sama, maka pertukaran tersebut dapat dipertukarkan dengan aman. Jika tidak, kita harus menunggu sampai alamat memori diakses oleh petunjuk yang diketahui. Karena kita tidak perlu benar-benar memprediksi nilai alamat, hanya apakah nilai tersebut  bertentangan, prediksi keduanya lebih stabil dan sederhana. Bentuk spekulasi nilai alamat terbatas ini telah digunakan di beberapa prosesor dan bisa menjadi universal di masa depan. 3.10

Studi Keterbatasan ILP

Pemanfaatan ILP untuk meningkatkan kinerja dimulai dengan prosesor pipelined  pertama di tahun 1960an. Pada tahun 1980an dan 1990an, teknik ini adalah kunci untuk mencapai peningkatan kinerja yang cepat. Pertanyaan tentang berapa banyak ILP ada sangat penting bagi kemampuan jangka panjang kita untuk meningkatkan kinerja pada tingkat yang melebihi peningkatan kecepatan teknologi sirkuit terpadu. Pada skala yang lebih pendek, pertanyaan kritis tentang apa yang dibutuhkan untuk mengeksploitasi lebih banyak ILP sangat penting bagi perancang komputer dan penulis kompiler. Data di bagian ini juga memberi kita sebuah cara untuk memeriksa nilai gagasan yang telah kita perkenalkan di bab ini, termasuk disambiguasi memori, daftar nama, dan spekulasi. Pada bagian ini, kami meninjau sebagian dari salah satu penelitian yang dilakukan terhadap pertanyaan-pertanyaan ini (berdasarkan studi Wall's 1993). Semua studi tentang paralelisme yang tersedia ini beroperasi dengan membuat seperangkat asumsi dan melihat seberapa banyak paralelisme tersedia berdasarkan asumsi-asumsi tersebut. Data yang kami teliti di sini berasal dari studi yang membuat asumsi paling sedikit; Sebenarnya, model perangkat keras utama mungkin tidak dapat direalisasi. Meskipun demikian, semua penelitian semacam itu mengasumsikan tingkat teknologi kompilator tertentu, dan beberapa asumsi ini dapat mempengaruhi hasilnya, terlepas dari penggunaan perangkat keras yang sangat ambisius. Seperti yang akan kita lihat, untuk model perangkat keras yang memiliki biaya terjangkau, tidak mungkin biaya spekulasi yang sangat agresif dapat dibenarkan:

inefisiensi dalam penggunaan dan penggunaan silikon terlalu ti nggi. Sementara banyak di komunitas riset dan produsen prosesor utama bertaruh mendukung ILP yang lebih dapat dieksploitasi dan pada awalnya enggan menerima kemungkinan ini, pada tahun 2005 mereka dipaksa untuk mengubah pikiran mereka. Model Perangkat Keras Untuk melihat berapa batasan ILP, pertama kita perlu mendefinisikan prosesor yang ideal. Prosesor ideal adalah satu di mana semua kendala pada ILP dilepaskan. Satusatunya batasan pada ILP dalam prosesor semacam itu adalah yang dipaksakan oleh arus data aktual melalui register atau memori. Asumsi yang dibuat untuk prosesor ideal atau sempurna adalah sebagai berikut: 1.

Infinite register renaming -- Ada jumlah register virtual yang tak terbatas yang

tersedia, dan karenanya semua bahaya WAW dan WAR dihindari dan sejumlah instruksi yang tak terbatas dapat mulai dijalankan bersamaan 2.

Perfect branch prediction -- Prediksi cabang sangat sempurna. Semua cabang

 bersyarat diprediksi persis. 3.

Perfect jump prediction -- Semua lompatan (termasuk lompatan register yang

digunakan untuk pengembalian dan lompatan dihitung) diprediksi dengan sempurna. Bila digabungkan dengan prediksi cabang yang sempurna, ini setara dengan memiliki  prosesor dengan spekulasi sempurna dan penyangga instruksi yang tak terbatas yang tersedia untuk eksekusi. 4.

Perfect memory address alias analysis -- Semua alamat memori diketahui secara

 pasti, dan sebuah beban dapat dipindahkan sebelum toko menyediakan alamatnya tidak identik. Perhatikan bahwa ini menerapkan analisis alias alamat sempurna. 5.

Perfect cache -- Semua akses memori mengambil satu siklus clock. Dalam

 prakteknya, prosesor superscalar biasanya akan mengkonsumsi sejumlah besar cache  penyembunyian ILP yang meleset, membuat hasil ini sangat optimis. Asumsi 2 dan 3 menghilangkan semua ketergantungan kontrol. Demikian juga, asumsi 1 dan 4 menghilangkan semua tapi ketergantungan data sebenarnya. Bersama-sama, keempat asumsi ini berarti bahwa setiap instruksi dalam pelaksanaan program dapat dijadwalkan pada siklus segera setelah eksekusi pendahulunya bergantung padanya. Bahkan mungkin, berdasarkan asumsi ini, untuk instruksi terakhir yang dieksekusi

secara dinamis dalam program yang akan dijadwalkan pada siklus pertama! Dengan demikian, kumpulan asumsi ini menggabungkan kedua kontrol dan mengatasi spekulasi dan menerapkannya seolah-olah mereka sempurna. Mengkonsumsi sejumlah besar cache penyembunyian ILP sangat jarang, membuat hasil ini sangat optimis. Instruksi sekaligus, terlihat sewenang-wenang jauh di depan dalam perhitungan. Untuk semua model prosesor yang kami teliti, tidak ada batasan jenis instruksi yang bisa dijalankan dalam satu siklus. Untuk kasus tanpa batas, ini berarti mungkin ada jumlah  beban atau toko yang tidak terbatas yang dikeluarkan dalam satu siklus clock. Selain itu, semua unit fungsional latensi diasumsikan satu siklus, sehingga setiap urutan instruksi dependen dapat diterbitkan pada siklus berturut-turut. Latensi yang lebih lama dari satu siklus akan mengurangi jumlah masalah per siklus, meski bukan jumlah instruksi yang di eksekusi pada titik mana pun. (Instruksi dalam eksekusi pada titik manapun sering disebut sebagai penerbangan.) Tentu saja, prosesor ideal ini mungkin tidak dapat direalisasikan. Sebagai contoh, IBM Power7 (lihat Wendell dkk., 2010) adalah prosesor superscalar yang paling canggih yang diumumkan sampai saat ini. Power7 mengeluarkan hingga enam instruksi per jam dan melakukan eksekusi pada 8 dari 12 unit eksekusi (hanya dua di antaranya adalah unit beban / toko), mendukung serangkaian besar daftar nama ulang (yang memungkinkan ratusan instruksi untuk digunakan dalam penerbangan), Menggunakan  prediktor cabang agresif yang besar, dan menggunakan disambiguasi ingatan dinamis. Power7 melanjutkan langkahnya untuk menggunakan paralelisme tingkat thread lebih  banyak dengan meningkatkan lebar dukungan multithreading simultan (SMT) (ke empat benang per inti) dan jumlah inti per chip menjadi delapan. Setelah melihat  paralelisme yang tersedia untuk prosesor yang sempurna, kami akan memeriksa apa yang mungkin dapat dicapai pada prosesor yang mungkin dir ancang dalam waktu dekat. sumbernya. Stasiun reservasi toko menunjukkan bahwa tujuan berlipat ganda adalah sumber nilai yang akan disimpan. Diumumkan sampai saat ini Power7 mengeluarkan hingga enam instruksi per  jam dan inisial eksekusi hingga 8 dari 12 unit eksekusi (hanya dua di antaranya adalah unit beban / toko), mendukung sejumlah besar daftar nama berganti nama (memungkinkan

ratusan

petunjuk

untuk

melakukannya

dalam

penerbangan),

menggunakan prediktor cabang agresif yang besar, dan menggunakan memori dinamis disambiguasi. Power7 melanjutkan langkahnya untuk menggunakan lebih banyak thread-level paralelisme dengan meningkatkan lebar simultan multithreading (SMT) support (sampai empat thread per inti) dan jumlah core per chip menjadi delapan. Setelah melihat paralelisme yang tersedia untuk prosesor yang sempurna, kita akan memeriksanya, apa yang mungkin bisa dicapai dalam setiap prosesor yang mungkin dirancang dalam waktu dekat. Untuk mengukur paralelisme yang ada, satu set program disusun dan dioptimalkan dengan standar MIPS yang mengoptimalkan kompiler. Programnya diinstrumentasi dan dijalankan untuk menghasilkan jejak instruksi dan data referensireferensi. Setiap instruksi di trace kemudian dijadwalkan sedini mungkin, terbatas hanya dengan ketergantungan data. Karena jejak digunakan, prediksi cabang yang sempurna, alias analisis yang sempurna itu mudah dilakukan. Dengan mekanisme ini, instruksinya mungkin dijadwalkan jauh lebih awal dari yang seharusnya, bergerak melintasi sejumlah instruksi yang tidak tergantung pada data, termasuk cabang, karena cabang diprediksi dengan sempurna. Gambar 3.26 menunjukkan jumlah rata-rata paralelisme yang tersedia untuk enam dari Benchmark SPEC92. Sepanjang bagian ini paralelisme diukur dengan tingkat instruksi rata-rata. Ingat bahwa semua instruksi memiliki satu siklus latensi; Latensi yang lebih panjang akan mengurangi jumlah instruksi rata-rata per jam. Tiga dari tolok ukur ini (fpppp, doduc, dan tomcatv) adalah floating-point intensif, dan tiga lainnya adalah program integer. Dua dari floating-point. Dua macam benchmark floating point (fpppp dan tomcatv) memiliki paralelisme yang luas, yang bisa jadi dieksploitasi oleh komputer vektor atau oleh multiprosesor (struktur di fpppp adalah cukup berantakan, karena beberapa transformasi tangan telah dilakukan di kode). Program doduc memiliki  paralelisme yang luas, namun paralelisme tidak terjadi pada loop paralel sederhana seperti pada fpppp dan tomcatv. Program tersebut adalah sebuah penerjemah LISP yang memiliki banyak ketergantungan pendek.

Keterbatasan ILP untuk Realisasi Prosesor

Pada bagian ini kita melihat kinerja prosesor dengan tingkat ambisius pada dukungan perangkat keras sama atau lebih baik dari pada yang tersedia di tahun 2011 atau, mengingat peristiwa dan pelajaran dalam dekade terakhir, kemungkinan akan tersedia dalam waktu dekat. Khususnya, kita asumsikan atribut tetap berikut ini: 1. Sampai 64 instruksi masalah per jam tanpa batasan masalah, atau lebih dari 10 kali total issue width dari prosesor terluas di tahun 2011. Seperti yang kita diskusikan kemudian, implikasi praktis dari lebar isu yang sangat luas pada  jam tingkat, kompleksitas logika, dan kekuatan mungkin merupakan keterbatasan yang paling penting memanfaatkan ILP 2. Prediktor turnamen dengan entri 1K dan prediktor prediksi 16 entri. Prediktor ini sebanding dengan prediktor terbaik di tahun 2011; Predikt or bukan sebuah hambatan utama 3. Sempurna disambiguasi referensi memori yang dilakukan secara dinamis ini ambisius tapi mungkin bisa dicapai untuk ukuran jendela kecil (dan karenanya masalah kecil rates dan load / store buffer) atau melalui address aliasing prediksi. 4. Daftar berganti nama dengan 64 tambahan integer dan 64 register FP tambahan, yang sedikit kurang dari prosesor yang paling agresif di tahun 2011. Intel Core i7 memiliki 128 entri dalam buffer pemesanan ulang,

meskipun tidak terbagi antara bilangan bulat dan FP, sedangkan IBM Power7 memiliki hampir 200. Perhatikan bahwa kita asumsikan latency pipa satu siklus, yang secara signifikan mengurangi kebutuhan untuk mengatur ulang entri penyangga. Baik Power7 dan i7 memiliki latency 10 siklus atau lebih. Gambar 3.27 menunjukkan hasil untuk konfigurasi ini karena kami memvariasikan jendela ukuran. Konfigurasi ini lebih kompleks dan mahal daripada mengimplementasikan, terutama dalam hal jumlah isu pengajaran, yang lebih banyak dari 10 kali lebih besar dari jumlah terbesar masalah yang tersedia pada prosesor apapun  pada tahun 2011. Meskipun demikian, ini memberi batasan yang berguna mengenai implementasi masa depan bisa menghasilkan data dalam angka ini cenderung sangat optimis bagi data lain alasan. Tidak ada batasan masalah di antara 64 instruksi: Semuanya mungkin ada referensi memori Tidak ada yang akan merenungkan kemampuan ini dalam prosesor dalam waktu dekat. Sayangnya, cukup sulit untuk mengimbangi performa dari prosesor dengan batasan masalah yang wajar; Tidak hanya ruang kemungkinan cukup besar, namun adanya pembatasan isu mengharuskan adanya  paralelisme dievaluasi dengan scheduler instruksi yang akurat, membuat biaya untuk mempelajari prosesor dengan sejumlah besar masalah sangat mahal. Selain itu, ingatlah bahwa dalam menafsirkan hasil ini cache misses dan nonunit latency belum diperhitungkan, dan kedua efek ini akan ada dampak yang signifikan!

Observasi yang paling mengejutkan dari Gambar 3.27 adalah bahwa, dengan  batasan prosesor realistis yang tercantum di atas, efek ukuran jendela untuk program  bilangan bulat tidak sekuruk program FP. Hasil ini menunjukkan perbedaan utama antara kedua jenis program ini. Tersedianya paralelisme tingkat loop dalam dua  program KB berarti jumlah ILP yang bisa dimanfaatkan adalah lebih ti nggi, tapi untuk  program integer faktor lain-seperti prediksi cabang, mendaftar berganti nama, dan kurang paralelisme, untuk memulai dengan - adalah semua keterbatasan penting. Pengamatan ini sangat penting karena adanya peningkatan penekanan pada bilangan  bulat kinerja sejak boomingnya World Wide Web dan cloud computing dimulai pada  pertengahan 1990-an. Memang, sebagian besar pertumbuhan pasar dalam dekade terakhir - pemrosesan transaksi, server Web, dan sejenisnya - bergantung pada kinerja integer, bukan floating point. Seperti yang akan kita lihat di bagian selanjutnya, untuk

yang realistis prosesor di tahun 2011, tingkat kinerja sebenarnya jauh lebih rendah dari itu ditunjukkan pada Gambar 3.27. Mengingat sulitnya meningkatkan kecepatan instruksi dengan perangkat keras yang realistis desain, desainer menghadapi tantangan dalam menentukan cara terbaik untuk menggunakan yang terbatas sumber daya yang tersedia di sirkuit terpadu Salah satu yang paling menarik trade-off adalah antara prosesor yang lebih sederhana dengan cache yang lebih besar dan clock rate yang lebih tinggi versus lebih menekankan pada  paralelisme tingkat instruksi dengan clock yang lebih lambat dan lebih kecil cache. Contoh berikut menggambarkan tantangan, dan di bab berikutnya kita akan melihat  pendekatan alternatif untuk mengeksploitasi paralelisme berbutir halus dibentu k GPU.

Di Luar Batas Studi Ini

Seperti halnya studi batas, penelitian yang telah kita bahas di bagian ini memiliki

kemampuan sendiri keterbatasan. Kami membagi ini menjadi dua kelas: keterbatasan yang muncul bahkan untuk prosesor spekulatif yang sempurna, dan keterbatasan yang timbul untuk satu atau lebih realistis model. Tentu saja, semua keterbatasan di kelas satu berlaku untuk yang kedua. Keterbatasan paling penting yang berlaku bahkan untuk model yang sempurna adalah 1. WAW dan WAR bahaya melalui memori. Studi ini menghilangkan WAW dan WAR melalui daftar nama berganti nama, namun tidak dalam  penggunaan memori. Meskipun sekilas mungkin tampak bahwa keadaan seperti itu jarang terjadi (terutama WAW bahaya), mereka timbul karena alokasi stack frame. Prosedur yang disebut menggunakan kembali lokasi memori dari prosedur sebelumnya pada tumpukan, dan hal ini dapat menyebabkan bahaya WAW dan WAR yang tidak perlu dibatasi. Austin dan Sohi [1992] memeriksa masalah ini. 2. Ketergantungan yang tidak perlu - Dengan jumlah register yang tak terbatas, semua tapi benar mendaftarkan dependensi data akan dihapus ada,  bagaimanapun, ketergantungan timbul dari kebiasaan rekurensi atau konvensi pembuatan kode yang diperkenalkan tetergantungan data yang

tidak perlu. Salah satu contohnya adalah ketergantungan pada variabel kontrol secara sederhana untuk loop. Karena variabel kontrolnya adalah  bertambah

pada

setiap

iterasi

loop,

loop

berisi

setidaknya

satu

ketergantungan. Seperti yang kita lihat di Appendix H, loop unrolling dan aljabar agresif optimasi dapat menghapus perhitungan dependen tersebut. Studi dinding meliputi sejumlah kecil pengoptimalan seperti itu, namun menerapkannya lebih agresif dapat menyebabkan peningkatan jumlah ILP. Selain itu, pembuatan kode tertentu konvensi mengenalkan ketergantungan yang tidak dibutuhkan, khususnya penggunaan pengembalian register ala mat dan register untuk stack pointer (yang bertambah dan decremented dalam urutan panggilan / kembali). Dinding menghapus efek dari register alamat  pengirim, namun penggunaan stack pointer pada konvensi keterkaitan dapat menyebabkan ketergantungan "tidak perlu". Postiff dkk. [1999] menjelajahi keuntungan menghilangkan kendala ini. 3. Mengatasi batas aliran data-Jika prediksi nilai bekerja dengan akurasi tinggi, maka bisa mengatasi batas aliran data. Sampai sekarang belum ada yang lebih dari itu 100 makalah tentang masalah ini telah mencapai peningkatan yang signifikan dalam ILP bila menggunakan skema prediksi yang realistis. Jelas,  prediksi nilai data yang yang sempurna akan menghasilkan menghasilkan paralelisme yang tidak terbatas secara efektif, karena setiap nilai setiap instruksi bisa diprediksi apriori. Untuk prosesor yang kurang sempurna, beberapa ide telah diajukan yang bisa dilakukan paparkan lebih banyak ban yak ILP. Salah satu contohnya adalah  berspekulasi dengan banyak jalur. Ide ini dibahas oleh Lam dan Wilson [1992] dan dieksplorasi dalam penelitian yang dibahas di sini bagian. Dengan  berspekulasi pada banyak jalur, biaya bi aya pemulihan yang salah akan berkurang dan lebih banyak paralelisme dapat ditemukan. Masuk akal untuk mengevaluasi skema ini untuk sejumlah cabang karena sumber daya  perangkat keras yang dibutuhkan d ibutuhkan tumbuh secara eksponensial. eksponensia l. Wall [1993] [ 1993] menyediakan data untuk berspekulasi di kedua arah sampai delapan cabang Mengingat biaya untuk mengejar kedua jalan itu, tahu itu akan dibuang (dan  jumlah perhitungan tak berguna seperti itu prosesnya diikuti melalui

 beberapa cabang), setiap desain komersialnya sebaliknya mencurahkan  perangkat keras tambahan untuk spekulasi yang lebih baik pada jalur yang  benar. Penting untuk dipahami bahwa tidak ada batasan dalam bagian ini yang mendasar dalam arti bahwa mengatasinya memerlukan perubahan dalam hukum fisika! Sebaliknya, mereka adalah keterbatasan praktis yang menyiratkan adanya beberapa yang tangguh hambatan untuk mengeksploitasi ILP tambahan. Keterbatasan ini-entah itu jendela ukuran, deteksi alias, atau prediksi cabang-mewakili tantangan bagi  perancang dan peneliti untuk mengatasinya. Upaya untuk menerobos batas-batas ini dalam lima tahun pertama abad ini  bertemu dengan frustrasi Beberapa teknik menghasilkan sedikit perbaikan, tapi sering di peningkatan kompleksitas yang signifikan, peningkatan siklus clock, dan  peningkatan daya yang tidak proporsional. Singkatnya, desainer menemukan bahwa mencoba ekstrak lebih banyak ILP terlalu tidak efisien. Kami akan kembali ke diskusi ini di ucapan penutup kami.

Isu Cross-Cutting: Pendekatan ILP dan Sistem Memori (Perangkat Keras versus Spekulasi Perangkat Lunak)

Pendekatan intensif perangkat keras untuk spekulasi dalam bab ini dan  pendekatan perangkat lunak Lampiran H memberikan pendekatan alternatif untuk mengeksploitasi ILP. Beberapa trade-off, dan keterbatasannya, untuk pendekatan ini tercantum di bawah ini: 

Untuk berspekulasi secara ekstensif, kita harus bisa membedakan referensi ingatan. Kemampuan ini sulit dilakukan pada waktu kompilasi untuk program integer yang berisi petunjuk. Dalam skema berbasis hardware, disambiguasi runtime dinamis alamat memori dilakukan dengan menggunakan teknik yang kita

lihat

sebelumnya

untuk

algoritma

Tomasulo.

Disambiguasi

ini

memungkinkan kita untuk memindahkan beban penyimpanan masa lalu saat runtime dukungan untuk referensi memori spekulatif dapat membantu atasi

konservatisme kompilator, tapi kecuali pendekatan seperti itu digunakan dengan hati-hati, overhead dari mekanisme pemulihan mungkin rawa keuntungan. 

Spekulasi berbasis hardware bekerja lebih baik bila arus kontrol tidak dapat diprediksi dan ketika prediksi cabang berbasis hardware lebih unggul daripada  perangkat lunak prediksi cabang dilakukan pada waktu kompilasi. Properti ini  berlaku untuk banyak program bilangan bulat. Misalnya, prediktor statis yang  bagus memiliki tingkat kesalahan penilaian sekitar 16% untuk empat program SPEC92 integer utama, dan peramal perangkat keras memiliki tingkat kesalahan  penilaian di bawah 10%. Karena speculated instructions dapat memperlambat  perhitungan saat prediksi salah, perbedaan ini signifikan. Salah satu hasil dari  perbedaan ini adalah bahwa prosesor yang dijadwalkan secara statis biasanya menyertakan prediktor cabang yang dinamis.



Spekulasi berbasis perangkat keras mempertahankan model pengecualian yang  benar-benar tepat bahkan untuk petunjuk berspekulasi. Pendekatan berbasis software terbaru menambahkan dukungan khusus untuk memungkinkan ini juga. Spekulasi berbasis hardware tidak memerlukan kompensasi atau pembukuan kode, yang dibutuhkan oleh mekanisme spekulasi perangkat lunak ambisius.



Pendekatan berbasis kompilator dapat memanfaatkan kemampuan untuk melihat lebih jauh di urutan kode, menghasilkan penjadwalan kode yang lebih baik daripada pendekatan hardwaredriven murni.



Spekulasi berbasis hardware dengan penjadwalan dinamis tidak memerlukan urutan kode yang berbeda untuk mencapai kinerja yang baik untuk implementasi arsitektur yang berbeda. Meski keunggulan ini adalah yang terberat untuk diukur, itu mungkin yang paling penting dalam jangka panjang. Menariknya, ini adalah salah satu dari motivasi untuk IBM 360/91. Di sisi lain, lebih baru secara eksplisit arsitektur paralel, seperti IA-64, telah menambahkan fleksibilitas yang mengurangi ketergantungan perangkat keras yang melekat dalam urutan kode.

Kerugian utama dari mendukung spekulasi di perangkat keras adalah kompleksitas dan sumber daya perangkat keras tambahan yang dibutuhkan. Biaya  perangkat keras ini harus dievaluasi baik kompleksitas kompilator untuk perangkat

lunak berbasis pendekatan dan jumlah dan kegunaan penyederhanaan dalam sebuah  prosesor itu bergantung pada kompilator semacam itu. Beberapa desainer telah mencoba menggabungkan dinamika dan kompilator  berbasis pendekatan untuk mencapai yang terbaik dari masing-masing. Kombinasi semacam itu dapat menghasilkan interaksi yang menarik dan tidak jelas. Misalnya, jika  pergerakan kondisional digabungkan dengan mendaftar ulang nama, efek samping yang halus muncul. Langkah kondisional itu dibatalkan masih harus menyalin nilai ke register tujuan, karena diganti namanya sebelumnya dalam instruksi pipeline. Interaksi halus ini mempersulit desain dan proses verifikasi dan juga bisa mengurangi performa. Prosesor Intel Itanium adalah komputer paling ambisius yang pernah dirancang Berdasarkan dukungan perangkat lunak untuk ILP dan spekulasi. Itu tidak menghasilkan harapan para desainer, terutama untuk tujuan umum, nonscientific code. Sebagai ambisi desainer untuk mengeksploitasi ILP berkurang karena kesulitan dibahas di Bagian 3.10, sebagian besar arsitektur diselesaikan pada mekanisme berbasis hardware dengan tingkat penerbitan tiga sampai empat instruksi per jam.

Eksekusi Spekulatif dan Sistem Memori

Inheren dalam prosesor yang mendukung eksekusi spekulatif atau instruksi  bersyarat adalah kemungkinan menghasilkan alamat tidak sah yang tidak akan terjadi tanpa eksekusi spekulatif. Hal ini tidak hanya akan menjadi perilaku yang salah jika  perlindungan pengecualian diambil, tapi manfaat eksekusi spekulatif akan terjadi dibanjiri oleh pengecualian palsu di atas kepala. Oleh karena itu, sistem memori harus mengidentifikasi instruksi yang dieksekusi secara spekulatif dan instruksi yang dijalankan secara kondisional dan menekan pengecualian yang sesuai Dengan alasan yang sama, kami tidak dapat mengizinkan instruksi tersebut menyebabkan tembolok macet karena ada lagi kios yang tidak perlu bisa membanjiri manfaatnya spekulasi. Oleh karena itu, prosesor ini harus disesuaikan dengan cache nonblocking. Pada kenyataannya, hukuman dari L2 miss begitu besar sehingga kompiler  biasanya saja berspekulasi pada L1 merindukan. Gambar 2.5 di halaman 84

menunjukkan bahwa untuk beberapa orang berperilaku baik program ilmiah kompilator dapat mempertahankan beberapa L2 yang beredar potong penalti kehilangan L2 secara efektif. Sekali lagi, agar ini bisa bekerja sistem memori di belakang tembolok harus sesuai dengan tujuan kompilator dalam jumlah akses memori simultan.

Multithreading: Memanfaatkan Thread-Level Paralelisme untuk Meningkatkan Throughput Uniprocessor

Topik yang kami bahas di bagian ini, multithreading, benar-benar topik lintas sektoral, karena memiliki relevansi dengan pipelining dan superscalar, hingga unit  pemrosesan grafis (Bab 4), dan untuk multiprosesor (Bab 5). Kami memperkenalkan topik di sini dan jelajahi penggunaan multithreading untuk meningkatkan throughput uniprocessor dengan menggunakan beberapa thread untuk menyembunyikan latensi  pipa dan memori. Di bab selanjutnya, kita akan melihat bagaimana multithreading memberikan keuntungan yang sama pada GPU, dan akhirnya, bab 5 akan mengeksplorasi kombinasi multithreading dan multiprocessing. Topik-topik ini terjalin erat, karena multithreading adalah teknik utama untuk mengekspos lebih paralelisme ke  perangkat keras. Dalam arti sempit, multithreading menggunakan paralelisme tingkatthread, dan dengan demikian subjek subjek Bab 5, namun demikian peran dalam memperbaiki pemanfaatan pipa dan di GPU memotivasi kita untuk mengenalkannya konsep di sini. Meski meningkatkan kinerja dengan menggunakan ILP memiliki keuntungan  besar cukup transparan bagi programmer, seperti yang telah kita lihat ILP bisa cukup terbatas atau sulit dieksploitasi dalam beberapa aplikasi. Secara khusus, dengan wajar tingkat instruksi, cache misses yang masuk ke memory atau off-chip caches tersebut tidak mungkin disembunyikan oleh ILP yang ada. Tentu saja, saat prosesor macet menunggu ketinggalan cache, pemanfaatan unit fungsional turun drastis. Semenjak upaya untuk menutup kios memori lama dengan lebih banyak ILP memiliki keefektifan yang terbatas, adalah wajar untuk menanyakan apakah bentuk  paralelisme lain dalam sebuah aplikasi bisa digunakan untuk menyembunyikan  penundaan memori. Misalnya, sistem pemrosesan transaksi online memiliki paralelisme

alami di antara banyak kueri dan pembaruan yang disajikan oleh permintaan. Tentu saja,  banyak aplikasi ilmiah mengandung paralelisme alam karena mereka sering memodelkan struktur alam tiga dimensi dan sejajar, dan struktur itu dapat dimanfaatkan dengan menggunakan thread terpisah. Bahkan aplikasi desktop yang menggunakan sistem operasi berbasis Windows modern sering memiliki beberapa aplikasi aktif yang  berjalan, memberikan sumber paralelisme. Multithreading memungkinkan beberapa thread untuk berbagi unit fungsional tunggal prosesor dengan cara yang tumpang tindih. Sebaliknya, metode yang lebih umum mengeksploitasi paralelisme thread-level (TLP) adalah dengan multiprosesor yang memiliki banyak thread independen beroperasi sekaligus dan paralel. Multithreading, bagaimanapun, tidak menduplikat keseluruhan prosesor sebagai multiprosesor. Sebagai gantinya, multithreading berbagi sebagian besar inti p rosesor di antara sekumpulan thread, menduplikat hanya negara swasta, seperti register dan counter program. Seperti yang akan kita lihat Bab 5, banyak prosesor terbaru menggabungkan kedua core prosesor pada satu chip dan menyediakan multithreading di dalam masing-masing inti. Duplikasi keadaan per-thread dari inti prosesor berarti menciptakan yang terpisah register file, PC yang terpisah, dan tabel halaman terpisah untuk setiap thread. Memori itu sendiri bisa dibagi melalui mekanisme memori virtual, yang sudah ada mendukung multiprogramming Selain itu, perangkat keras harus mendukung kemampuannya ubah thread yang berbeda dengan relatif cepat; Khususnya, sebuah saklar thread harus jauh lebih efisien daripada switch proses, yang biasanya membutuhkan ratusan sampai ribuan siklus prosesor. Tentu saja, untuk perangkat keras multithreading

untuk

mencapai

peningkatan

kinerja,

sebuah

program

harus

mengandung banyak thread (terkadang kita bilang aplikasi itu multithreaded) yang bisa dijalankan secara bersamaan. Thread ini diidentifikasi oleh kompilator (biasanya dari  bahasa dengan konstruksi paralelisme) atau oleh pemrogram. Ada tiga pendekatan hardware utama untuk multithreading. Berbutir halus switch multithreading antara thread pada setiap jam, menyebabkan eksekusi instruksi dari beberapa thread untuk disisipkan. Interleaving ini sering terjadi dilakukan dengan cara round-robin, melewatkan semua thread yang terhenti saat itu.

Salah satu keuntungan utama dari multithreading berbutir halus adalah bahwa ia dapat menyembunyikan kerugian throughput yang timbul dari kios pendek dan panjang, karena petunjuk dari yang lain thread bisa dieksekusi saat satu kios thread, kalaupun kiosnya hanya untuk beberapa siklus. Kerugian utama dari multithreading berbutir halus adalah melambat turunkan eksekusi thread individu, karena thread yang siap dieksekusi tanpa kios akan tertunda oleh instruksi dari thread lainnya. Ini memperdagangkan sebuah uncrease pada throughput multithread karena kehilangan kinerja (seperti yang diukur oleh latency) dari satu thread. Prosesor Sun Niagara, yang kami periksa tak lama lagi, gunakan multithreading berbutir halus sederhana, seperti halnya GPU Nvidia, yang mana kita lihat di bab berikutnya. Multithreading berbutir kasar ditemukan sebagai alternatif untuk berbutir halus multithreading Switch multithreading berbutir kasar hanya pada biaya mahal kios, seperti tingkat dua atau tiga cache misses. Perubahan ini mengurangi kebutuhan memiliki thread-switching pada dasarnya bebas dan cenderung untuk melambat eksekusi satu thread, karena instruksi dari thread lain hanya akan ada dikeluarkan saat sebuah thread menemukan sebuah kios mahal. Multithreading berbutir kasar menderita, bagaimanapun, dari kelemahan utama: Ini adalah terbatas dalam kemampuannya mengatasi kerugian throughput, teru tama dari yang lebih pendek kios Keterbatasan ini timbul dari biaya start-up pipa yang kasar multithreading Karena CPU dengan instruksi multithreading berbutir kasar instruksi dari satu thread, ketika sebuah kios terjadi, pipa akan melihat sebuah gelembung. Sebelum thread baru mulai dijalankan. Karena overhead start-up ini, multithreading  berbutir kasar jauh lebih berguna untuk mengurangi hukuman kios sangat mahal, di mana isi ulang pipa bisa diabaikan dibandingkan dengan kiosnya waktu. Beberapa  proyek penelitian telah mengeksplorasi multithreading berbutir kasar, namun tidak ada  prosesor arus utama yang menggunakan teknik ini. Implementasi multithreading yang paling umum disebut Simultaneous Multithreading (SMT). Simultan multithreading adalah variasi pada multithreading finegrained yang muncul secara alami ketika multithreading berbutir halus adalah diimplementasikan di atas beberapa masalah, prosesor yang dijadwalkan secara dinamis. Seperti bentuk multithreading lainnya, SMT menggunakan paralelisme tingkat

thread untuk disembunyikan peristiwa laten-latency dalam sebuah prosesor, sehingga meningkatkan pemakaian fungsional unit. Wawasan kunci di SMT adalah mendaftarkan nama dan penjadwalan dinamis izinkan beberapa petunjuk dari benang independen untuk dieksekusi tanpa memperhatikan ketergantungan di antara mereka; Resolusi ketergantungannya bisa jadi ditangani oleh kemampuan penjadwalan yang dinamis. Gambar 3.28 secara konseptual menggambarkan perbedaan kemampuan  prosesor memanfaatkan sumber daya superscalar untuk konfigurasi prosesor berikut: 

Superscalar tanpa dukungan multithreading



Superscalar dengan multithreading berbutir kasar



Superscalar dengan multithreading berbutir halus



Superscalar dengan multithreading simultan

Pada superscalar tanpa dukungan multithreading, penggunaan slot isu ini dibatasi oleh kekurangan ILP, termasuk ILP untuk menyembunyikan latency memori. Karena panjang cache L2 dan L3 merindukan, sebagian besar prosesor bisa dibiarkan menganggur.

Pada superscalar multithread berbutir kasar, kios-kios panjang sebagian tersembunyi dengan beralih ke thread lain yang menggunakan sumber daya prosesor. Peralihan ini mengurangi jumlah siklus clock yang benar-benar menganggur. Secara kasar prosesor multithreading berbutir, bagaimanapun, switching benang hanya terjadi saat ada kios. Karena thread baru memiliki periode start-up, ada kemungkinan besar  beberapa siklus idle masih tersisa. Dalam kasus halus, interleaving benang bisa menghilangkan sepenuhnya kosong slot. Selain itu, karena benang penerbitan berubah pada setiap siklus clock, operasi latensi yang lebih lama bisa disembunyikan. Karena masalah instruksi dan eksekusi terhubung, thread hanya bisa mengeluarkan banyak instruksi seperti yang sudah siap. Dengan isu sempit lebar ini tidak menjadi masalah (sebuah siklus baik yang ditempati atau tidak), yang mana mengapa multithreading berbutir halus bekerja sempurna untuk  prosesor edisi tunggal, dan SMT tidak masuk akal. Memang, di Matahari T2, ada dua isu per jam, tapi dari benang yang berbeda. Ini menghilangkan kebutuhan untuk menerapkan pendekatan penjadwalan dinamis yang kompleks dan bergantung pada latency tersembunyi dengan lebih banyak benang. Jika seseorang menerapkan threading halus di atas dynami multiple-issue  prosesor cally schedule, hasilnya adalah SMT. Dalam semua implementasi SMT yang ada, semua masalah berasal dari satu thread, walaupun instruksi dari berbagai thread  bisa berbeda memulai eksekusi dalam siklus yang sama, dengan menggunakan  perangkat keras penjadwalan dinamis tentukan instruksi apa yang siap Meskipun Gambar 3.28 sangat menyederhanakannya operasi sebenarnya dari prosesor ini, memang menggambarkan potensi kinerja kelebihan multithreading pada umumnya dan SMT dalam isu yang lebih luas, dinamis prosesor terjadwal Multithreading simultan menggunakan wawasan yang dijadwalkan secara dinamis prosesor sudah memiliki banyak mekanisme perangkat keras yang dibutuhkan untuk mendukung mekanisme, termasuk set virtual register besar. Multithreading dapat dibangun di atas bagian atas prosesor yang tidak dipesan dengan menambahkan tabel  penggantian nama per-thread PC terpisah, dan menyediakan kemampuan untuk instruksi dari banyak benang untuk melakukan.

Efektivitas Multithreading berbutir halus pada Sun T1

Pada bagian ini, kita menggunakan prosesor Sun T1 untuk menguji kemampuan multithreading untuk menyembunyikan latency T1 adalah multicore multithreading  berbutir halus mikroprosesor diperkenalkan oleh Sun pada tahun 2005. Apa yang membuat T1 sangat menarik adalah bahwa hal itu hampir sepenuhnya terfokus pada  pemanfaatan paralelisme tingkat-thread (TLP) daripada instruksi tingkat paralelisme (ILP). T1 meninggalkan intens fokus pada ILP (hanya sesaat setelah prosesor ILP paling agresif yang pernah ada diperkenalkan), kembali ke strategi pipa sederhana, dan  berfokus pada pemanfaatan TLP, menggunakan kedua core dan multithreading untuk menghasilkan throughput. Setiap prosesor T1 berisi delapan core prosesor, masing-masing mendukung empat benang. Setiap inti prosesor terdiri dari enam tahap sederhana, satu masalah pipa (standar pipa RISC lima tahap seperti Lampiran C, dengan satu tahap ditambahkan untuk benang switching). T1 menggunakan multithreading berbutir halus (tapi tidak SMT), beralih ke yang baru benang pada setiap siklus clock, dan benang yang menganggur karena mereka menunggu karena

Sebuah delay pipa atau cache miss dilewati dalam penjadwalan. Prosesornya menganggur Hanya jika keempat benang itu menganggur atau terhenti. Baik beban dan cabang menimbulkan tiga Penundaan siklus yang hanya bisa disembunyikan oleh

 benang lainnya. Satu set floating point Unit fungsional dibagi oleh semua delapan inti, karena kinerja floating-point bukan a Fokus untuk T1. Gambar 3.29 merangkum  prosesor T1.

T1 Multithreading Unicore Performance

T1 menjadikan TLP sebagai fokusnya, baik melalui multithreading pada individu Inti dan melalui penggunaan banyak inti sederhana pada satu mati. Pada bagian ini, kita Akan melihat keefektifan T1 dalam meningkatkan kinerja single Inti melalui multithreading berbutir halus. Pada Bab 5, kita akan kembali untuk memeriksa Keefektifan penggabungan multithreading dengan banyak core. Untuk memeriksa kinerja T1, kami menggunakan tiga server yang berorientasi  pada bench Tanda: TPC-C, SPECJBB (Benchmark Bisnis Java SPEC), dan SPECWeb99. Karena banyak benang meningkatkan permintaan memori dari satu  prosesor, mereka Dapat membebani sistem memori, yang menyebabkan pengurangan  potensi keuntungan Multithreading Gambar 3.30 menunjukkan kenaikan relatif pada tingkat rindu dan Diamati miss latency ketika mengeksekusi dengan satu thread per inti versus mengeksekusi Empat benang per inti untuk TPC-C. Tingkat miss dan latency miss meningkat, Karena meningkatnya pertengkaran dalam sistem memori. Kenaikan relatif kecil di Miss latency menunjukkan bahwa sistem memori masih memiliki kapasitas yang tidak terpakai. Dengan melihat perilaku benang rata-rata, kita bisa mengerti interac Antara  benang dan kemampuan mereka untuk tetap sibuk. Gambar 3.31 menunjukkan Persentase siklus dimana thread dijalankan, siap tapi tidak dieksekusi, dan belum siap. Ingat bahwa tidak siap tidak menyiratkan bahwa inti dengan benang itu adalah Terhenti; Hanya jika keempat benang itu tidak siap maka intinya akan macet. Thread bisa tidak siap karena cache misses, delay pipa (timbul dari Instruksi latensi panjang seperti cabang, beban, floating point, atau integer Kalikan / bagilah), dan berbagai efek yang lebih kecil. Gambar 3.32 menunjukkan relatif

Frekuensi berbagai penyebab ini. Efek cache bertanggung jawab atas benang yang tidak siap dari 50% sampai 75% dari waktu, dengan instruksi L1 merindukan, data L1

merindukan, dan L2 merindukan berkontribusi kira-kira sama. Penundaan potensial dari  pipa (yang disebut "delay pipa") paling parah pada SPECJBB dan mungkin timbul dari frekuensi cabang yang lebih tinggi.

Gambar 3.33 menunjukkan CPI per-thread dan per-core. Karena T1 adalah  prosesor multithread berbutir halus dengan empat benang per inti, dengan lelismenya  paral yang cukup, CPI efektif ideal per benang adalah empat, karena itu berarti setiap

 benang menghabiskan satu siklus dari setiap empat. CPI ideal per inti akan menjadi satu. Pada tahun 2005, IPC untuk benchmark yang berjalan pada inti ILP yang agresif ini akan serupa dengan yang terlihat pada inti T1. Inti T1, bagaimana pun, berukuran sangat sederhana dibandingkan dengan core ILP yang agresif di tahun 2005, oleh karena itu T1 memiliki delapan core dibandingkan dua sampai empat yang ditawarkan pada  prosesor lain dari vintage yang sama. Sebagai hasilnya, pada tahun 2005 ketika diperkenalkan, prosesor Sun T1 memiliki kinerja terbaik pada aplikasi integer dengan TLP exten sive dan kinerja memori yang menuntut, seperti SPECJBB dan beban kerja  pemrosesan transak tion.

Efektivitas Multithreading simultan pada Prosesor Superscalar

Pertanyaan kunci adalah, Seberapa besar kinerja dapat diperoleh dengan menerapkan SMT? Ketika pertanyaan ini dieksplorasi pada tahun 2000-2001, para  periset mengasumsikan bahwa superscalar dinamis akan semakin jauh dalam lima tahun ke depan, mendukung enam sampai delapan isu per jam dengan penjadwalan dinamis spekulatif, banyak beban dan toko simultan, cache primer yang besar, dan empat Ke delapan konteks dengan isu simul taneous dan pensiun dari berbagai konteks. Tidak ada  prosesor yang mendekati level ini. Akibatnya, hasil penelitian simulasi yang menunjukkan kenaikan beban kerja multipro grammed dua kali atau lebih tidak realistis. Dalam prakteknya, implementasi SMT yang ada hanya menawarkan dua sampai empat konteks dengan pengambilan dan  penerbitan dari hanya satu, dan sampai empat isu per jam. Hasilnya adalah bahwa keuntungan dari SMT juga lebih rendah. Sebagai contoh, di Pentium 4 Extreme, seperti yang diterapkan pada server HPCompaq, penggunaan SMT menghasilkan peningkatan kinerja 1,01 saat menjalankan  benchmark SPECintRate dan sekitar 1,07 saat menjalankan benchmark SPECfpRate. Tuck dan Tullsen [2003] melaporkan bahwa, pada tolok ukur paralel SPLASH, mereka menemukan single-core multithreaded speedups mulai dari 1,02 sampai 1,67, dengan kecepatan rata-rata sekitar 1,22.

Dengan tersedianya pengukuran ekstensif dan mendalam terkini yang dilakukan oleh Esmaeilzadeh et al. [2011], kita bisa melihat kinerja dan manfaat energi menggunakan SMT di satu inti i7 dengan menggunakan seperangkat aplikasi multithread. Tolok ukur yang kami gunakan terdiri dari kumpulan aplikasi ilmiah  paralel dan satu set program Java multithread dari paket DaCapo dan SPEC Java, seperti yang dirangkum dalam Gambar 3.34. Intel i7 mendukung SMT dengan dua benang. Gambar 3.35 menunjukkan rasio kinerja dan rasio efisiensi energi dari tolok ukur ini  berjalan pada satu inti i7 dengan SMT dimatikan dan dinyalakan. (Kami merencanakan rasio efisiensi energi, yang merupakan kebalikan dari konsumsi energi, sehingga, seperti kecepatan tinggi, rasio yang lebih tinggi lebih baik.) Mean harmonik dari  percepatan untuk tolok ukur Java adalah 1,28, meskipun ada dua tolok ukur yang melihat keuntungan kecil. . Kedua tolok ukur ini, pjbb2005 dan kacang-kacangan  perdagangan, sementara multithreaded, memiliki paralelisme terbatas. Mereka disertakan karena mereka merupakan ciri khas benchmark multithread yang dapat dijalankan pada seorang probe SMT dengan harapan bisa mengeluarkan beberapa kinerja, yang mereka temukan dalam jumlah terbatas. Tolok ukur PARSEC mendapatkan kecepatan yang agak lebih baik daripada tolok ukur Java (mean harmonik 1,31). Jika tradebeans dan pjbb2005 dihilangkan, beban kerja Java sebenarnya akan memiliki kecepatan yang jauh lebih baik (1,39) daripada tolok ukur PARSEC. (Lihat  pembahasan implikasi kita dengan cara yang harmonis untuk merangkum hasilnya dalam caption pada Gambar 3.36). Konsumsi energi ditentukan oleh kombinasi kecepatan dan peningkatan konsumsi daya. Untuk tolok ukur Java, rata-rata, SMT memberikan efisiensi energi yang sama dengan non-SMT (rata-rata 1,0), namun diturunkan oleh dua tolok ukur kinerja buruk; Tanpa tradebeans dan pjbb2005, rata-rata

Efisiensi energi untuk benchmark Java adalah 1,06, yang hampir sama baiknya dengan tolok ukur PARSEC. Dalam tolok ukur PARSEC, SMT mengurangi energi sebesar 1 (1 / 1.08) = 7%. Penyempurnaan kinerja pengurangan energi semacam itu sangat sulit ditemukan. Tentu saja, kekuatan statis yang terkait dengan TPS dibayarkan dalam kedua kasus tersebut, sehingga hasilnya mungkin sedikit melebih-lebihkan keuntungan energi. Hasil ini menunjukkan dengan jelas bahwa SMT dalam prosesor spekulatif yang agresif dengan dukungan ekstensif untuk SMT dapat meningkatkan kinerjanya secara efisien energi, yang oleh pendekatan ILP yang lebih agresif tidak berhasil dilakukan. Pada tahun 2011, keseimbangan antara beberapa core yang lebih sederhana dan core sophisticat yang lebih sedikit telah bergeser mendukung core yang lebih banyak, dengan masing-masing inti biasanya menjadi superscalar tiga sampai empat dengan SMT yang mendukung dua sampai empat benang. Memang, Esmaeilzadeh dkk. [2011]

menunjukkan bahwa peningkatan energi dari SMT lebih besar pada prosesor Intel i5 (prosesor yang serupa dengan i7, namun dengan cache yang lebih kecil dan tingkat clock yang lebih rendah) dan Intel Atom (prosesor 80 × 86 yang dirancang untuk pasar netbook Dan dijelaskan pada Bagian 3.14).

Menempatkan semuanya bersama-sama: The Intel Core i7 dan ARM Cortex-A8

Pada bagian ini kita membahas dua prosesor multi masalah: inti ARM CortexA8, yang digunakan sebagai dasar untuk prosesor Apple A9 di iPad, serta prosesor di Motorola Droid dan iPhone 3GS dan 4 , Dan Intel Core i7, prosesor spekulatif highend, dinamis yang dijadwalkan, ditujukan untuk aplikasi desktop dan server kelas atas. Kita mulai dengan prosesor sim pler.

ARM Cortex-A8

A8 adalah dual-issue, superscalar yang dijadwalkan secara statistik dengan deteksi masalah dinamis, yang memungkinkan prosesor mengeluarkan satu atau dua instruksi per jam. Gambar 3.36 menunjukkan struktur pipa dasar dari pipa 13 tahap. A8 menggunakan prediktor cabang yang dinamis dengan penyiapan target dua arah sebanyak 512 entri dan target penyangga cabang gabungan dan penyangga sejarah global 4K, yang diindeks oleh riwayat cabang dan PC saat ini. Jika tar cabang mendapatkan buffer misses, sebuah prediksi diperoleh dari buffer sejarah global, yang kemudian dapat digunakan untuk menghitung alamat cabang. Selain itu, tumpukan kembali delapan entri disimpan untuk melacak alamat pengirim. Prediksi yang salah menghasilkan hukuman 13-siklus karena pipanya memerah. Gambar 3.37 menunjukkan instruksi decode pipeline. Sampai dua instruksi per  jam bisa dikeluarkan dengan menggunakan mekanisme in-order issue. Struktur papan skor sederhana digunakan untuk melacak kapan sebuah instruksi dapat diterbitkan. Sepasang instruksi dependen dapat diproses melalui logika masalah, tapi tentu saja, mereka akan diserialkan di papan skor, kecuali jika dapat diterbitkan sehingga jalur  penerusan dapat mengatasi ketergantungan tersebut. Gambar 3.38 menunjukkan pipa eksekusi untuk prosesor A8. Entah instruktur 1 atau instruksi 2 bisa menuju ke pipa beban / toko. Sepenuhnya melewati adalah porting sup di antara jaringan pipa. Pipa ARM Cortex-A8 menggunakan dua superscalar statis yang dijadwalkan secara sederhana untuk memungkinkan tingkat jam cukup tinggi

dengan daya rendah. Sebaliknya, i7 menggunakan struktur dynami empat hari yang cukup agresif, terjadwal struktur pipa spekulatif.

Kinerja Pipa A8

A8 memiliki IHK ideal 0,5 karena struktur dual-issue. Warung pipa bisa timbul dari tiga sumber: 1. Bahaya fungsional, yang terjadi karena dua instruksi berdekatan dipilih untuk masalah secara simultan menggunakan pipa fungsional yang sama. Karena A8 dijadwalkan secara statis, tugas kompilator untuk menghindari konflik semacam itu. Ketika mereka tidak dapat dihindari, A8 dapat mengeluarkan  paling banyak satu instruksi dalam siklus itu. Puting It All Together: Intel Core i7 dan ARM Cortex-A8

2. Bahaya data, yang terdeteksi di awal jalur pipa dan mungkin macet baik kedua instruksi (jika yang pertama tidak dapat mengeluarkannya, yang kedua selalu macet) atau yang kedua dari pasangan. Kompilator bertanggung jawab untuk mencegah warung tersebut bila memungkinkan. 3. Kendalikan bahaya, yang timbul hanya bila cabang salah paham. Selain warung pipa, L1 dan L2 merindukan keduanya menyebabkan warung. Gambar 3.39 menunjukkan perkiraan faktor-faktor yang berkontribusi terhadap CPI aktual untuk tolok ukur Minnespec, yang kami lihat di Bab 2. Seperti yang dapat kita lihat, penundaan jalur pipa daripada kios memori merupakan penyumbang utama CPI. Hasil ini sebagian disebabkan oleh efek  bahwa Minnespec memiliki jejak cache yang lebih kecil daripada SPEC  penuh atau program besar lainnya.

Wawasan bahwa kios-kios pipa menciptakan kerugian kinerja yang signifikan mungkin memainkan peran kunci dalam keputusan untuk membuat ARM Cortex-A9 sebagai superscalar yang dijadwalkan secara dinamis. A9, seperti A8, mengeluarkan hingga dua instruksi per jam, namun menggunakan penjadwalan dan spekulasi dinamis. Sampai empat instruksi yang tertunda (dua ALU, satu load / store atau FP / multimedia, dan satu cabang) dapat memulai eksekusi dalam siklus clock. A9 menggunakan  prediktor cabang yang lebih kuat, prefetch cache instruksi, dan cache data L1 nonblocking. Gambar 3.40 menunjukkan bahwa A9 mengungguli A8 dengan faktor 1,28 rata-rata, dengan asumsi tingkat clock yang sama dan konfigurasi cache yang hampir sama.

Intel Core i7

i7 menggunakan mikroarsitektur spekulatif out-of-order yang agresif dan memiliki jalur pipa dalam dengan tujuan mencapai throughput instruksi tinggi dengan menggabungkan beberapa masalah dan tingkat clock yang tinggi. Gambar 3.41 menunjukkan keseluruhan struktur pipa i7. Kami akan memeriksa pipa dengan memulai dengan

instruksi mengambil dan melanjutkan ke instruksi komit, mengikuti langkahlangkah yang diberi label pada gambar. 1. Instruction fetch-Processor menggunakan buffer target bertingkat untuk mencapai keseimbangan antara kecepatan dan akurasi prediksi. Ada juga tumpukan alamat pengirim untuk mempercepat fungsi return. Mispredictions menyebabkan pena alty sekitar 15 siklus. Dengan menggunakan alamat  prediksi, unit pengambilan instruksi mengambil 16 byte dari cache instruksi. 2. 16 byte ditempatkan pada buffer instruksi predecode-Pada langkah ini, sebuah proses yang disebut makro-op fusion dieksekusi. Macro-op fusion mengambil kombinasi instruc tion seperti membandingkan diikuti oleh cabang dan sekering mereka menjadi satu operasi. Tahap predecode juga memecahkan 16 byte menjadi instruksi individu x86. Predecode ini tidak  penting karena panjang x86 I\instruksi bisa dari 1 sampai 17 byte dan  predecoder harus melihat melalui sejumlah byte sebelum mengetahui  panjang instruksi. Instruksi x86 individu (termasuk beberapa instruksi menyatu) ditempatkan ke antrian instruksi 18-entri. 3. 3. Micro-op decode-Instruksi x86 individu diterjemahkan ke dalam mikro-ops. Micro-ops adalah instruksi sederhana seperti MIPS yang dapat dieksekusi secara langsung oleh pipa; Pendekatan ini menerjemahkan instruksi x86 ke dalam operasi sederhana yang lebih mudah pipelined diperkenalkan di Pentium Pro pada tahun 1997 dan telah digunakan sejak saat itu. Tiga dari dekoder menangani instruksi x86 yang diterjemahkan langsung menjadi satu mikro-op. Untuk instruksi x86 yang memiliki semantik lebih kompleks, ada mesin microcode yang digunakan untuk menghasilkan urutan mikro-op; Itu dapat menghasilkan hingga empat mikro-ops setiap siklus dan berlanjut sampai urutan mikro-op yang diperlukan telah dihasilkan. Micro-ops ditempatkan sesuai urutan instruksi x86 pada buffer op-op entri 28-entri. 4. Penyangga mikro-op preforms deteksi aliran loop dan mikrofusi - Jika ada urutan instruksi kecil (kurang dari 28 instruksi atau panjang 256 byte) yang terdiri dari satu lingkaran, detektor aliran loop akan menemukan loop dan secara langsung mengeluarkan Mikro-ops dari buffer, menghilangkan

kebutuhan akan instruksi fetch dan instruction decode stages yang akan diaktifkan. Microfu sion menggabungkan pasangan instruksi seperti operasi load / ALU dan operasi ALU / store dan mengeluarkannya ke satu stasiun reservasi tunggal (dimana mereka masih dapat mengeluarkannya secara mandiri), sehingga meningkatkan penggunaan buffer. Dalam sebuah studi arsitektur Intel Core, yang juga menggabungkan microfusion dan macrofu sion, Bird et al. [2007] menemukan bahwa microfusion memiliki dampak kecil pada per formance, sementara macrofusion tampaknya memiliki dampak positif sederhana pada kinerja bilangan bulat dan sedikit dampak  pada kinerja floating-point. 5. Lakukan masalah instruksi dasar-Menengok lokasi register di tabel register, mengganti daftar register, mengalokasikan entri buffer reorder, dan mengambil hasil dari register atau menyusun ulang buffer sebelum mengirim mikro-op ke stasiun reservasi. 6. i7 menggunakan stasiun reservasi terpusat 36 pintu yang dibagi oleh enam unit fungsional. Sampai enam mikro ops dapat dikirim ke unit fungsional setiap siklus clock. 7. Micro-ops dijalankan oleh unit fungsi individual dan kemudian hasilnya dikirim kembali ke stasiun reservasi tunggu dan juga unit pensiunan  pensiunan, di mana mereka akan memperbarui status register, setelah diketahui bahwa instruksi tersebut tidak ada Lagi spekulatif Entri yang sesuai dengan instruksi dalam buffer pemesanan ulang ditandai sebagai selesai. 8. Bila satu atau lebih instruksi di kepala penyangga ulang telah ditandai sebagai selesai, penulisan yang tertunda di unit pensiun register dijalankan, dan  petunjuknya dikeluarkan dari buffer pemesanan ulang.

Kinerja i7

Pada bagian sebelumnya, kami memeriksa kinerja prediksi cabang i7 dan juga kinerja TPS. Pada bagian ini, kita melihat kinerja pipa single-thread. Karena adanya spekulasi agresif dan juga cache yang tidak menghalangi, sulit untuk mengaitkan

kesenjangan antara kinerja ideal dan kinerja aktual secara akurat. Seperti yang akan kita lihat, relatif sedikit warung terjadi karena petunjuk tidak dapat diterbitkan. Misalnya, hanya sekitar 3% dari beban yang tertunda karena tidak ada stasiun reservasi yang tersedia. Sebagian besar kerugian berasal dari misprediks cabang atau tembolok tembolok. Biaya mispredict cabang adalah 15 siklus, sementara biaya kehilangan L1 adalah sekitar 10 siklus; L2 merindukan sedikit lebih dari tiga kali lebih mahal daripada kehilangan L1, dan L3 merindukan biaya sekitar 13 kali lipat dari biaya kehilangan L1 (siklus 130-135)! Meskipun prosesor akan mencoba menemukan petunjuk alternatif untuk dieksekusi agar L3 merindukan dan beberapa L2 merindukan, kemungkinan  beberapa buffer akan terisi sebelum rilisan selesai, menyebabkan prosesor berhenti mengeluarkan instruksi. Untuk memeriksa biaya mispredicts dan spekulasi yang salah, Gambar 3.42 menunjukkan fraksi pekerjaan (diukur dengan jumlah mikro-op yang dikirim ke pipa) yang tidak berhenti (yaitu, hasil mereka dibatalkan).

relatif terhadap semua kiriman mikro-op. Untuk sjeng, misalnya, 25% pekerjaan terbuang sia-sia, karena 25% dari op-amp mikro yang dikirim tidak akan pernah  pensiun. Perhatikan bahwa pekerjaan yang terbuang dalam beberapa kasus sangat sesuai dengan tingkat kesalahan missi cabang yang ditunjukkan pada Gambar 3.5 di halaman 167, namun dalam beberapa kasus, seperti MCF, pekerjaan terbuang tampaknya relatif lebih besar daripada tingkat kesalahan penilaian. Dalam kasus tersebut, kemungkinan  penjelasan muncul dari perilaku memori. Dengan tingkat kehilangan cache data yang sangat tinggi, mcf akan mengirimkan banyak instruksi selama spekulasi yang tidak pasti selama tersedia stasiun reservasi yang memadai untuk referensi memori yang macet. Bila kecurigaan cabang terdeteksi, mikro-op yang sesuai dengan petunjuk ini akan dimerah, tapi akan ada kemacetan di sekitar cache, karena referensi memori yang dipetik mencoba untuk menyelesaikannya. Tidak ada cara sederhana bagi prosesor untuk menghentikan permintaan cache seperti itu setelah dimulai. Gambar 3.43 menunjukkan keseluruhan IHK untuk tolok ukur SPECCPU2006 19. Tolok ukur integer memiliki IHK 1,06 dengan varians sangat besar (0,67 stan dard deviation). MCF dan OMNETPP adalah pencetus utama, keduanya memiliki CPI lebih dari 2,0 sementara tolok ukur lainnya mendekati, atau kurang dari 1,0 (gcc, tertinggi  berikutnya, adalah 1,23). Perbedaan ini berasal dari perbedaan ketepatan cabang

 prediksi dan tingkat kehilangan cache. Untuk tolok ukur integer, tingkat kehilangan L2 adalah prediktor terbaik CPI, dan tingkat kehilangan L3 (yang sangat kecil) hampir tidak berpengaruh. Tolok ukur FP mencapai kinerja yang lebih tinggi dengan IHK rata-rata yang lebih rendah (0,89) dan standar deviasi yang lebih rendah (0,25). Untuk tolok ukur FP, L1 dan L2 sama pentingnya dalam menentukan CPI, sementara L3 memainkan peran yang lebih kecil namun signifikan. Sementara kemampuan penjadwalan dan nonblocking yang dinamis dari i7 dapat menyembunyikan beberapa latency miss,  perilaku memori cache masih merupakan penyumbang utama. Ini memperkuat peran multithreading sebagai cara lain untuk menyembunyikan latensi memori.

Kesalahan

Kelemahan kami sedikit berfokus pada kesulitan memprediksi kinerja dan efisiensi energi dan mengekstrapolasi dari ukuran tunggal seperti clock rate atau CPI. Kami juga menunjukkan bahwa pendekatan arsitektural yang berbeda dapat memiliki  perilaku yang berbeda secara radikal untuk tolok ukur yang berbeda. Mudah untuk memprediksi kinerja dan efisiensi energi dari dua versi yang  berbeda dari arsitektur set instruksi yang sama, jika kita memegang teknologi konstan. Intel memproduksi sebuah prosesor untuk Netbook low-end dan ruang PMD yang sangat mirip dengan mikroarsitektur ARM A8, yang disebut Atom 230. Inter dengan pasti, Atom 230 dan Core i7 920 keduanya telah dibuat dalam 45 nm yang sama. Teknologi Intel Gambar 3.44 merangkum Intel Core i7, ARM Cortex-A8, dan Intel Atom 230. Kesamaan ini memberi kesempatan langka untuk secara langsung membandingkan dua mikroarsitektur yang berbeda secara radikal untuk set instruksi yang sama sambil tetap memegang teknologi pembuatan yang mendasarinya. Sebelum kita melakukan perbandingan, kita perlu mengatakan sedikit lebih banyak tentang Atom 230. Prosesor Atom menerapkan arsitektur x86 menggunakan nique teknologi st andar untuk menerjemahkan instruksi x86 ke dalam instruksi seperti RISC (karena setiap implementasi x86 sejak pertengahan 1990an telah Selesai). Atom menggunakan

mikrooperation mikro yang sedikit lebih pandai, yang memungkinkan operasi aritmatika dipasangkan dengan beban atau toko. Ini berarti bahwa rata-rata untuk campuran instruksi khas hanya 4% dari instruksi memerlukan lebih dari satu operasi mikro. Operasi mikro kemudian dieksekusi dalam pipa 16-dalam yang mampu mengeluarkan dua instruksi per jam, sesuai urutan, seperti pada ARM A8. Ada ALUs dual-integer, jalur pipa terpisah untuk FP add dan operasi FP lainnya, dan dua jaringan operasi memori, mendukung eksekusi ganda yang lebih umum daripada ARM A8 namun masih dibatasi oleh kemampuan dalam urutan masalah. Atom 230 memiliki cache instruksi 32 KB dan cache data 24 KB, keduanya didukung oleh shared 512 KB L2 pada die yang sama. (Atom 230 juga mendukung multithreading de ngan dua benang, namun kami hanya akan mempertimbangkan satu perbandingan ulir tunggal.) Gambar 3.46 merangkum prosesor i7, A8, dan Atom dan karakteristik utamanya. Kita bisa berharap bahwa kedua prosesor ini, yang diimplementasikan dalam teknologi yang sama dan dengan set instruksi yang sama, akan menunjukkan perilaku yang dapat diprediksi, dalam

istilah kinerja relatif dan konsumsi energi, yang berarti bahwa kekuatan dan kinerja akan mendekati secara linear. Kami memeriksa hipotesis ini dengan menggunakan tiga tolok ukur. Set pertama adalah sekelompok Java, tolok ukur single-threaded yang  berasal dari tolok ukur DaCapo, dan tolok ukur SPEC JVM98 (lihat Esmaeilzadeh dkk. [2011] untuk diskusi tentang tolok ukur dan pengukuran). Set kedua dan ketiga dari  benchmark adalah dari SPEC CPU2006 dan terdiri dari tolok ukur integer dan FP. Seperti yang dapat kita lihat pada Gambar 3.45, i7 secara signifikan lebih unggul dari Atom. Semua tolok ukur setidaknya empat kali lebih cepat pada i7, dua benchmark SPECFP lebih dari sepuluh kali lebih cepat, dan satu benchmark SPECINT berjalan lebih dari delapan kali lebih cepat!

Karena rasio tingkat clock kedua prosesor ini adalah 1,6, sebagian besar keuntungan berasal dari CPI yang jauh lebih rendah untuk i7: faktor 2,8 untuk tolok

ukur Java, faktor 3,1 untuk benchmark SPECINT, dan faktor 4.3 Untuk benchmark SPECFP. Tapi, konsumsi daya rata-rata untuk i7 hanya di bawah 43 W, sedangkan konsumsi daya rata-rata Atom adalah 4,2 W, atau sekitar sepersepuluh dari daya! Menggabungkan kinerja dan kekuatan menghasilkan keunggulan efisiensi energi untuk Atom yang biasanya lebih dari 1,5 kali lebih baik dan sering kali 2 kali lebih baik! Perbandingan dua prosesor dengan menggunakan nology teknologi dasar yang sama memperjelas bahwa keunggulan kinerja supersca agresif dengan penjadwalan dinamis dan spekulasi datang dengan kerugian yang signifikan dalam efisiensi energi. Prosesor dengan CPI yang lebih rendah akan selalu lebih cepat. Prosesor Fallacy dengan clock rate yang lebih cepat akan selalu lebih cepat. Kuncinya adalah produk CPI dan clock rate yang menentukan kinerja. Tingkat clock yang tinggi yang diperoleh dengan sangat pipelining CPU harus mempertahankan CPI rendah untuk mendapatkan manfaat penuh dari jam yang lebih cepat. Begitu pula dengan prosesor sederhana dengan clock rate tinggi namun CPI rendah bisa lebih lambat. Seperti yang kita lihat dalam kekeliruan sebelumnya, kinerja dan efisiensi energi dapat menyimpang secara signifikan di antara prosesor yang dirancang untuk lingkungan yang berbeda bahkan ketika mereka memiliki ISA yang sama. Sebenarnya,  perbedaan kinerja yang besar dapat muncul bahkan dalam keluarga prosesor dari  perusahaan yang sama yang semuanya dirancang untuk aplikasi kelas atas. Gambar 3.46 menunjukkan kinerja integer dan FP dari dua implementasi yang berbeda dari arsitektur x86 dari Intel, serta versi arsitektur Itanium, juga oleh Intel. Pentium 4 adalah prosesor pipelined yang paling agresif yang pernah dibangun oleh Intel. Ini menggunakan pipa dengan lebih dari 20 tahap, memiliki tujuh unit fungsional, dan menyimpan mikro-ops alih-alih instruksi x86. Kinerja yang relatif inferior mengingat penerapan yang agresif, merupakan indikasi yang jelas bahwa upaya untuk mengeksploitasi lebih banyak ILP (mudah ada 50 instruksi dalam penerbangan) telah gagal. Konsumsi daya Pentium sama dengan i7, meskipun jumlah transistornya lebih rendah, karena cache utamanya setengah besar seperti i7, dan hanya mencakup cache sekunder 2 MB tanpa tembolok tersier.

Intel Itanium adalah arsitektur bergaya VLIW, yang walaupun memiliki potensi  penurunan dalam kompleksitas dibandingkan dengan superscalar yang dijadwalkan secara dinamis, tidak pernah mencapai tingkat clock kompetitif dengan prosesor x86 utama (walaupun tampaknya mencapai CPI keseluruhan yang serupa dengan i7). Dalam memeriksa hasil ini, pembaca harus sadar bahwa mereka menggunakan teknologi implementasi yang berbeda, sehingga memberikan keuntungan dalam hal kecepatan transistor dan karenanya tingkat clock untuk prosesor pipelined ekuivalen. Meskipun demikian, variasi kinerja yang luas - lebih dari tiga kali antara Pentium dan i7 menakjubkan. Perangkap berikutnya menjelaskan di mana sejumlah besar keuntungan ini berasal.

Sebagian besar perhatian pada awal tahun 2000an digunakan untuk membangun  prosesor agresif untuk mengeksploitasi ILP, termasuk arsitektur Pentium 4, yang menggunakan pipa terdalam yang pernah ada di mikroprosesor, dan Intel Itanium, yang memiliki tingkat tertinggi pada tingkat tertinggi per jam yang pernah ada. . Yang cepat menjadi jelas adalah bahwa keterbatasan utama dalam mengeksploitasi ILP sering kali ternyata adalah sistem memori. Meskipun jaringan pipa out-of-order spekulatif cukup  bagus untuk menyembunyikan pecahan yang signifikan dari 10 sampai 15 siklus melewatkan hukuman untuk tingkat pertama, mereka dapat melakukan sedikit sekali untuk menyembunyikan hukuman karena tingkat kedua merindukan itu, Saat pergi ke memori utama, kemungkinan akan menjadi 50 sampai 100 jam siklus. Hasilnya adalah bahwa desain ini tidak pernah mendekati pencapaian throughput instruksi puncak meskipun jumlah transistor besar dan teknik yang sangat canggih dan cerdas. Bagian selanjutnya membahas dilema ini dan berpalingnya dari skema ILP yang

lebih agresif ke multicore, namun ada perubahan lain yang mencontohkan perangkap ini. Alih-alih mencoba menyembunyikan latency memori lebih banyak lagi dengan ILP,  perancang hanya menggunakan transistor untuk membangun cache yang jauh lebih  besar. Baik Itanium 2 dan i7 menggunakan cache tingkat tiga dibandingkan cache dua tingkat Pentium 4, dan cache tingkat ketiga adalah 9 MB dan 8 MB dibandingkan dengan cache tingkat 2 MB Pentium 4. Tak perlu dikatakan, membangun cache yang lebih besar jauh lebih mudah daripada merancang 20 + stage Pentium 4 pipeline dan, dari data pada Gambar 3.46, tampaknya lebih efektif.

Penutup: Apa yang di Depan?

Sejak tahun 2000, fokus pada pemanfaatan paralelisme tingkat instruksi mencapai puncaknya. Intel akan mengenalkan Itanium, prosesor berurutan dengan tingkat tinggi yang mengandalkan prosesor VLIW dengan dukungan kompiler intensif. Prosesor MIPS, Alpha, dan IBM dengan ekspedisi spekulatif yang dijadwalkan secara dinamis berada di generasi kedua dan semakin lebar dan lebih cepat. Pen Ti um 4, yang menggunakan penjadwalan spekulatif, juga telah diumumkan pada tahun itu dengan tujuh unit fungsional dan jalur pipa lebih dari 20 tahap. Tapi ada awan badai di cakrawala. Penelitian seperti yang tercakup dalam Bagian 3.10 menunjukkan bahwa mendorong ILP jauh lebih jauh akan sangat sulit, dan, sementara instruksi puncak melalui tingkat suku bunga telah meningkat dari prosesor spekulatif pertama sekitar 3 sampai 5 tahun sebelumnya, tingkat eksekusi instruksi yang berkelanjutan semakin meningkat perlahan. Lima tahun berikutnya menceritakan. Itanium ternyata adalah seorang  profesional procc FP tapi hanya prosesor integer biasa-biasa saja. Intel masih menghasilkan garis, tapi tidak banyak pengguna, tingkat clocknya tertinggal dari  prosesor Intel garis utama, dan Microsoft tidak lagi mendukung set instruksi. Intel Pentium 4, sementara mencapai kinerja yang baik, ternyata tidak efisien dalam hal kinerja / watt (yaitu penggunaan energi), dan kompleksitas prosesor membuat tidak mungkin kemajuan lebih lanjut dimungkinkan dengan meningkatkan tingkat

 penerbitan. Itu akhir dari jalan 20 tahun untuk mencapai tingkat kinerja baru dalam mikroprosesor dengan memanfaatkan ILP telah tiba. Pentium 4 secara luas diakui telah melampaui titik pengembalian yang berkurang, dan mikroarsitektur Netburst yang agresif dan canggih telah ditinggalkan. Pada tahun 2005, Intel dan semua produsen prosesor utama lainnya telah mengubah pendekatan mereka untuk fokus pada multicore. Kinerja yang lebih tinggi akan dicapai melalui paralelisme tingkat-thread daripada paralelisme tingkat instruksi, dan tanggung jawab untuk menggunakan prosesor secara efisien akan banyak beralih dari perangkat keras ke perangkat lunak dan pemrogram. Perubahan ini adalah  perubahan arsitektur arsitektur prosesor yang paling signifikan sejak hari-hari awal pipelining dan  paralelisme tingkat instruksi sekitar 25+ tahun sebelumnya. Selama periode yang sama, perancang mulai mengeksplorasi penggunaan  paralelisme tingkat data lebih banyak sebagai pendekatan lain untuk mendapatkan kinerja. Ekstensi SIMD memungkinkan mikroprosesor desktop dan server untuk mencapai peningkatan kinerja moderat untuk grafis dan fungsi serupa. Yang lebih  penting lagi, unit pemrosesan grafis (GPU) mengejar penggunaan SIMD secara secara agresif, mencapai keuntungan perfor mance yang signifikan untuk aplikasi dengan paralelisme tingkat data yang luas. Untuk aplikasi ilmiah, pendekatan semacam itu mewakili alternatif yang layak untuk paralelisme thread-level yang lebih umum namun kurang efisien yang dieksploitasi di multicore. Bab berikutnya membahas perkembangan  penggunaan paralelisme tingkat data ini. Banyak peneliti meramalkan penghematan besar dalam penggunaan ILP, memperkirakan bahwa dua prosesor superscalar dan sejumlah besar core akan menjadi masa depan. Keuntungannya, bagaimanapun, dengan tingkat masalah yang sedikit lebih tinggi dan kemampuan penjadwalan dinamis spekulatif untuk menghadapi kejadian yang tidak dapat diprediksi, seperti tingkat cache yang salah, menyebabkan ILP moderat menjadi blok bangunan utama uta ma dalam desain multicore. Penambahan SMT dan efektivitasnya (baik untuk efisiensi dan efisiensi energi) selanjutnya memperkuat posisi  pendekatan moderat, out-of-order, spekulatif. Memang, bahkan di ket ketenam,  prosesor terbaru (misalnya, ARM Cortex-A9) telah memperkenalkan penjadwalan dinamis, spekulasi, dan tingkat masalah yang lebih luas.

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF