Bagaimana cara kerja prediksi cabang, jika Anda masih harus memeriksa kondisinya?

30

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)

Akhir
sumber
1
Ini wiki Artikel melakukan pekerjaan yang cukup baik menjelaskan itu.
enderland
8
CPU modern disalurkan melalui jaringan dan dapat melakukan beberapa hal pada saat yang bersamaan. Dengan demikian ia dapat mulai mengeksekusi tebakannya sementara masih mencari tahu jika tebakannya benar. Jika tebakannya benar, saluran pipa terus berjalan. Pada tebakan yang salah, pipa dibuang dan eksekusi dimulai kembali dari titik "jawaban yang benar".
markspace
2
Bacaan terkait: pipa . Saya juga merekomendasikan membaca ulang jawaban yang diterima pada pertanyaan SO itu, karena menjawab pertanyaan Anda di sini.

Jawaban:

19

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:

  1. memancarkan isi PC ("register program register") ke bus alamat;
  2. baca instruksi opcode dari bus data;
  3. kenaikan PC;
  4. decode opcode untuk mencari tahu apa yang harus dilakukan dengannya;
  5. memancarkan isi PC ke bus alamat;
  6. baca operan instruksi (dalam hal ini 10) dari bus data;
  7. kenaikan PC;
  8. beri makan operan dan SI ke penambah;
  9. memancarkan hasil dari penambah ke bus alamat;
  10. baca AX dari bus data.

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, seperti MUL AX, operandyang 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.

Mike Nakis
sumber
2
Huh, saya bertanya-tanya apakah sebagian dari masalah yang orang (termasuk saya) miliki tentang memahami ini adalah sangat sulit (bagi saya toh) untuk membayangkan seorang cpu hanya memiliki pengetahuan parsial dari satu instruksi saja; atau untuk memiliki banyak instruksi setengah jadi "melalui oven pizza belt" ... bagi saya setidaknya, rasanya seperti perubahan skala ke atom ketika saya terbiasa bekerja dengan hal-hal antara set erector dan tingkat bubut logam.
StarWeaver
1
@ StarWeaver Saya menyukai komentar Anda, jadi saya mengubah jawaban saya untuk mengatasinya.
Mike Nakis
1
Wow, eksplorasi yang bagus. Saya cenderung lupa berapa banyak yang masuk hanya dengan memindahkan kata ke lokasi yang lebih berguna. Saya masih memvisualisasikan cpu sebagai seperangkat oven pizza yang digerakkan oleh sabuk: 3.
StarWeaver
Perlu diingat bahwa pertanyaan Stack Overflow yang ditautkan oleh OP - pertanyaan dengan 1,3 juta tampilan yang mungkin memperkenalkan lebih dari 1 juta programmer pada fakta yang sebelumnya tidak dikenal bahwa "prediksi cabang" bahkan ada - menunjukkan contoh di Jawa . Bagi orang-orang seperti saya yang terbiasa bekerja pada tingkat abstraksi yang diberikan bahasa seperti Jawa, bahkan orang MOV AX,[SI+10]asing, bukan "sederhana"; kebanyakan programmer saat ini tidak pernah menulis. Kami tidak "secara naif menganggap" itu berarti apa-apa.
Mark Amery
@MarkAmery yah, oke, saya pikir agak jelas bahwa dengan "kita manusia" maksudku "kita manusia yang berani menulis majelis". Poin yang dibuat adalah bahwa bahkan programmer bahasa assembly tidak memikirkan pipa sepanjang waktu, atau bahkan sama sekali.
Mike Nakis
28

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.

Karl Bielefeldt
sumber
2
Penjelasan ini rapi.
sharptooth
2

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.

Anjing
sumber
1

Bentuk pendek:

Beberapa CPU dapat mulai mengerjakan instruksi baru sebelum menyelesaikan yang lama. Ini adalah CPU yang menggunakan prediksi cabang.

Contoh pseudocode:

int globalVariable;
int Read(int* readThis, int* readThat)
{
    if ((globalVariable*globalVariable % 17) < 5)
       return *readThis;
    else
       return *readThat;
}

Kode di atas memeriksa suatu kondisi dan berdasarkan pada hasil yang dibutuhkan untuk mengembalikan nilai yang disimpan di lokasi memori addThisatau nilai yang disimpan di readThat. Jika prediksi cabang memprediksi kondisi yang akan terjadi true, CPU sudah akan membaca nilai yang disimpan di lokasi memori addThissambil melakukan perhitungan yang diperlukan untuk mengevaluasi ifpernyataan itu. Ini adalah contoh yang disederhanakan.

Peter
sumber
1

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:

  1. Anda memulai esai Anda tentang topik yang salah dan harus meninggalkan apa yang telah Anda tulis sejauh ini. Anda harus mulai menulis tentang topik lain dan itu adalah upaya waktu yang sama seolah-olah Anda telah menunggu.
  2. Anda menebak dengan benar dan Anda sudah melakukan pekerjaan.

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.

Otomo
sumber