Saya membaca jawaban populer tentang Prediksi Cabang dari https://stackoverflow.com/q/11227809/555690 , dan ada sesuatu yang membingungkan saya:
- Jika Anda menebak dengan benar, itu berlanjut.
- Jika Anda salah menebak, kapten akan berhenti, mundur, dan berteriak kepada Anda untuk membalik sakelar. Kemudian dapat memulai kembali di jalur lain.
Jika Anda menebak dengan benar setiap waktu, kereta tidak akan pernah berhenti.
Jika Anda salah menebak terlalu sering, kereta akan menghabiskan banyak waktu untuk berhenti, mencadangkan, dan memulai kembali.
Tapi ini yang tidak saya dapatkan: untuk mengetahui apakah tebakan Anda benar atau salah, Anda harus tetap memeriksa kondisi . Jadi, bagaimana prediksi cabang bekerja, jika Anda masih melakukan pemeriksaan bersyarat yang sama?
Yang ingin saya katakan adalah, bukankah prediksi cabang sama persis dengan tidak memiliki prediksi cabang sama sekali karena Anda melakukan pemeriksaan bersyarat yang sama? (jelas saya salah, tapi saya tidak mengerti)
sumber
Jawaban:
Tentu saja kondisinya diperiksa setiap saat. Tetapi pada saat itu diperiksa, itu jauh ke dalam pipa CPU. Sementara itu, instruksi lain juga telah memasuki pipa, dan berada pada berbagai tahap pelaksanaan.
Biasanya, suatu kondisi segera diikuti oleh instruksi cabang bersyarat, yang cabang baik jika kondisi mengevaluasi ke TRUE, atau jatuh melalui jika kondisi mengevaluasi ke FALSE. Ini berarti bahwa ada dua aliran instruksi yang berbeda yang dapat dimuat ke dalam pipa setelah instruksi kondisi dan instruksi cabang, tergantung pada apakah kondisi mengevaluasi ke TRUE atau FALSE. Sayangnya, segera setelah memuat instruksi kondisi dan instruksi cabang, CPU belum tahu kondisi apa yang akan dievaluasi, tetapi masih harus tetap memuat barang-barang ke dalam pipa. Jadi ia mengambil salah satu dari dua set instruksi berdasarkan dugaan seperti apa kondisi yang akan dievaluasi.
Kemudian, ketika instruksi kondisi melewati pipa, sekarang saatnya untuk dievaluasi. Pada saat itu, CPU mengetahui apakah tebakannya benar atau salah.
Jika tebakan ternyata benar, maka cabang pergi ke tempat yang benar, dan instruksi yang tepat dimuat ke dalam pipa. Jika ternyata dugaan itu salah, maka semua instruksi yang dimuat ke dalam pipa setelah instruksi cabang bersyarat salah, mereka harus dibuang, dan pengambilan instruksi harus dimulai lagi dari tempat yang tepat.
Amandemen
Menanggapi komentar StarWeaver, untuk memberikan gambaran tentang apa yang harus dilakukan CPU untuk menjalankan satu instruksi:
Anggap sesuatu yang sesederhana
MOV AX,[SI+10]
yang oleh manusia kita anggap naif sebagai "memuat AXE dengan kata di SI plus 10". Secara kasar, CPU harus:Ini adalah 10 langkah kekalahan. Beberapa langkah-langkah ini akan dioptimalkan jauh bahkan dalam CPU non-pipeline, misalnya CPU akan hampir selalu meningkatkan PC secara paralel dengan langkah berikutnya, yang merupakan hal yang mudah dilakukan karena PC adalah register yang sangat, sangat istimewa yang tidak pernah digunakan untuk pekerjaan lain, jadi tidak ada kemungkinan pertikaian antara berbagai bagian CPU untuk akses ke register khusus ini. Tapi tetap saja, kita dibiarkan dengan 8 langkah untuk instruksi yang begitu sederhana, dan perhatikan bahwa saya sudah mengasumsikan tingkat kecanggihan atas nama CPU, misalnya saya mengasumsikan bahwa tidak perlu untuk seluruh langkah ekstra untuk penambah untuk benar-benar melakukan penambahan sebelum hasilnya dapat dibaca dari itu,
Sekarang, pertimbangkan bahwa ada mode pengalamatan yang lebih rumit, seperti
MOV AX, [DX+SI*4+10]
, dan bahkan instruksi yang jauh lebih rumit, sepertiMUL AX, operand
yang benar-benar melakukan loop di dalam CPU untuk menghitung hasilnya.Jadi, maksud saya di sini adalah metafora "level atom" jauh dari cocok untuk level instruksi CPU. Mungkin cocok untuk tingkat langkah pipa, jika Anda tidak ingin pergi terlalu jauh ke tingkat gerbang logika yang sebenarnya.
sumber
MOV AX,[SI+10]
asing, bukan "sederhana"; kebanyakan programmer saat ini tidak pernah menulis. Kami tidak "secara naif menganggap" itu berarti apa-apa.Anggap saja seperti perjalanan tanpa GPS. Anda datang ke persimpangan, dan berpikir Anda perlu berputar, tetapi tidak sepenuhnya yakin. Jadi Anda mengambil belokan, tetapi minta penumpang Anda untuk memeriksa peta. Mungkin Anda berada tiga mil di jalan saat Anda selesai berdebat tentang di mana Anda berada. Jika Anda benar, Anda tiga mil lebih jauh dari yang seharusnya jika Anda berhenti dan berdebat sebelum berbalik. Jika Anda salah, Anda harus berbalik.
Pipeline CPU bekerja dengan cara yang sama. Pada saat mereka dapat memeriksa kondisinya, mereka sudah berada di ujung jalan. Perbedaannya adalah, mereka tidak harus mengemudi tiga mil ke belakang, mereka hanya kehilangan kepala. Itu berarti tidak ada salahnya mencoba.
sumber
Dari pemahaman saya, prediksi cabang paling berguna ketika kondisi yang perlu Anda periksa membutuhkan hasil dari sesuatu yang mahal atau masih dalam proses, dan Anda akan memutar-mutar ibu jari Anda menunggu nilai untuk mengevaluasi kondisi tersebut.
Dengan hal-hal seperti eksekusi out-of-order, Anda dapat menggunakan prediksi cabang untuk mulai mengisi titik-titik kosong dalam pipa yang CPU tidak akan dapat digunakan. Dalam situasi di mana tidak ada, untuk beberapa alasan, siklus idle dalam pipa, maka ya, tidak ada keuntungan dalam prediksi cabang.
Tapi kuncinya di sini adalah, CPU mulai bekerja untuk salah satu cabang yang diprediksi karena belum dapat mengevaluasi kondisinya sendiri.
sumber
Bentuk pendek:
Beberapa CPU dapat mulai mengerjakan instruksi baru sebelum menyelesaikan yang lama. Ini adalah CPU yang menggunakan prediksi cabang.
Contoh pseudocode:
Kode di atas memeriksa suatu kondisi dan berdasarkan pada hasil yang dibutuhkan untuk mengembalikan nilai yang disimpan di lokasi memori
addThis
atau nilai yang disimpan direadThat
. Jika prediksi cabang memprediksi kondisi yang akan terjaditrue
, CPU sudah akan membaca nilai yang disimpan di lokasi memoriaddThis
sambil melakukan perhitungan yang diperlukan untuk mengevaluasiif
pernyataan itu. Ini adalah contoh yang disederhanakan.sumber
Ya, kondisinya diperiksa baik. Tetapi keuntungan dari prediksi cabang adalah Anda dapat melakukan pekerjaan alih-alih menunggu hasil pemeriksaan kondisi.
Katakanlah Anda harus menulis esai dan bisa mengenai topik A atau topik B. Anda tahu dari esai sebelumnya bahwa guru Anda menyukai topik A lebih baik daripada B dan memilihnya lebih sering. Alih-alih menunggu keputusannya, Anda dapat mulai menulis esai tentang topik pertama. Sekarang ada dua hasil yang mungkin:
CPU modern sering tidak beroperasi karena menunggu respons IO atau hasil perhitungan lainnya. Waktu ini dapat digunakan untuk melakukan beberapa pekerjaan di masa depan.
Sekalipun Anda harus mengabaikan apa yang Anda lakukan dalam waktu tidak aktif ini - kemungkinan besar akan lebih efektif jika Anda memiliki kemampuan untuk menebak jalur mana yang akan dipilih oleh program. Dan CPU modern memiliki kemampuan ini.
sumber