Mengapa pembagian perangkat keras membutuhkan waktu lebih lama daripada perkalian?

37

Mengapa pembagian perangkat keras memakan waktu lebih lama daripada multiplikasi pada mikrokontroler? Misalnya, pada dsPIC, sebuah divisi membutuhkan 19 siklus, sedangkan multiplikasi hanya membutuhkan satu siklus clock.

Saya telah melalui beberapa tutorial, termasuk algoritma Division dan algoritma Multiplication di Wikipedia. Ini alasan saya.

Algoritma pembagian, seperti metode pembagian lambat dengan memulihkan di Wikipedia, adalah algoritma rekursif. Ini berarti bahwa (perantara) hasil dari langkah kdigunakan sebagai input ke langkah k+1, yang berarti bahwa algoritma ini tidak dapat diparalelkan. Oleh karena itu, dibutuhkan setidaknya nsiklus untuk menyelesaikan pembagian, sedangkan nsejumlah bit dalam dividen. Untuk dividen 16-bit, ini sama dengan setidaknya 16 siklus.

Algoritma multiplikasi tidak perlu bersifat rekursif, yang artinya dimungkinkan untuk memparalelkannya. Namun, ada banyak algoritma multiplikasi yang berbeda, dan saya tidak memiliki petunjuk yang mana yang dapat digunakan oleh mikrokontroler. Bagaimana cara kerja multiplikasi pada perangkat keras / mikrokontroler?

Saya telah menemukan algoritma pengali Dadda , yang seharusnya hanya membutuhkan satu siklus clock untuk menyelesaikannya. Namun, yang tidak saya dapatkan di sini adalah bahwa algoritma Dadda menghasilkan dalam tiga langkah, sedangkan hasil dari langkah 1 digunakan pada langkah 2, dll. Menurut ini, ini akan memakan waktu setidaknya tiga siklus jam untuk menyelesaikannya.

Marko Gulin
sumber
2
Algoritma tidak benar-benar menentukan jumlah siklus clock. CPU spesifik Anda mungkin memiliki pengali / pembagi perangkat keras yang bekerja dalam satu siklus atau 20 siklus terlepas dari implementasi internal.
Eugene Sh.
1
OP, dapatkah Anda memberikan tautan yang memberikan informasi lebih lanjut tentang siklus 19 vs 1 yang Anda bicarakan? Sesuatu yang spesifik tentang DSP Anda.
Vladimir Cravero
1
Terima kasih atas jawabannya. Berikut ini adalah lembar data untuk mikrokontroler saya: ww1.microchip.com/downloads/en/DeviceDoc/70005127c.pdf . Lihat Ikhtisar set instruksi, mulai dari halaman 292. Dikatakan bahwa semua instruksi DIV memerlukan 18 siklus, sementara semua instruksi MUL hanya membutuhkan 1 siklus. Tetapi tidak umum hanya untuk MCU ini, saya pernah melihat ini di banyak MCU lainnya.
Marko Gulin
2
@ Burd, well, mereka hampir sama, bukan? Apakah untuk saya. Saya tidak berpikir itu menggambarkannya sebaik yang Anda bayangkan.
TonyM
1
Faktor lainnya adalah ekonomi dan pola penggunaan. Sebagian besar penggunaan memanggil jauh lebih sering daripada membagi. Mendedikasikan area besar silikon untuk fungsi membagi perangkat keras yang lebih cepat yang akan digunakan relatif jarang adalah ekonomi yang buruk. Lebih baik membuat chip yang lebih kecil dan lebih murah, atau menggunakan logika ekstra dengan cara yang lebih produktif. BTW ketika saya mulai dengan minicomputer, divide tidak selalu merupakan instruksi. Pada beberapa mesin itu adalah panggilan pustaka perangkat lunak, seperti root kuadrat.
nigel222

Jawaban:

34

Sebuah pembagi memetakan jauh lebih tidak elegan ke perangkat keras biasa. Ambil Lattice ICE40 FPGAs sebagai contoh.

Mari kita bandingkan dua kasing: pengganda 8x8 bit hingga 16 bit ini:

module multiply (clk, a, b, result);
   input clk;
   input [7:0]a;
   input [7:0]b;
   output [15:0]result;
   always @(posedge clk)
     result = a * b;
endmodule // multiply

dan pembagi ini yang mengurangi operan 8 dan 8 bit menjadi 8 bit:

module divide(clk, a, b, result);
   input clk;
   input [7:0] a;
   input [7:0] b;
   output [7:0] result;
   always @(posedge clk)
     result = a / b;
endmodule // divide

(Ya, saya tahu, jamnya tidak melakukan apa - apa)

Gambaran umum dari skema yang dihasilkan saat memetakan pengali ke ICE40 FPGA dapat ditemukan di sini dan pembagi di sini .

Statistik sintesis dari Yosys adalah:

berkembang biak

  • Jumlah kabel: 155
  • Jumlah bit kawat: 214
  • Jumlah kabel publik: 4
  • Jumlah bit kawat publik: 33
  • Jumlah kenangan: 0
  • Jumlah bit memori: 0
  • Jumlah proses: 0
  • Jumlah sel: 191
    • SB_CARRY 10
    • SB_DFF 16
    • SB_LUT4 165

membagi

  • Jumlah kabel: 145
  • Jumlah bit kawat: 320
  • Jumlah kabel publik: 4
  • Jumlah bit kawat publik: 25
  • Jumlah kenangan: 0
  • Jumlah bit memori: 0
  • Jumlah proses: 0
  • Jumlah sel: 219
    • SB_CARRY 85
    • SB_DFF 8
    • SB_LUT4 126

Perlu dicatat bahwa ukuran Verilog yang dihasilkan untuk pengali lebar penuh dan pembagi pembagi maksimal tidak terlalu ekstrem. Namun, jika Anda melihat gambar-gambar di bawah ini, Anda akan melihat bahwa pengali mungkin memiliki kedalaman 15, sedangkan pembagi lebih mirip 50 atau lebih; jalur kritis (yaitu jalur terpanjang yang dapat terjadi selama operasi) adalah apa yang menentukan kecepatan!


Anda tidak akan bisa membaca ini, untuk mendapatkan kesan visual. Saya pikir perbedaan dalam kompleksitas mungkin dikenali. Ini adalah pengali / pembagi siklus tunggal!

Berkembang biak

Lipat gandakan pada ICE40 (peringatan: ~ gambar 100 Mpixel)

Gambar skala multiplier

Membagi

( Bagilah pada ICE40 ) (peringatan: ~ gambar 100 Mpixel)

Gambar skala pembagi

Marcus Müller
sumber
4
tidak, Anda bisa menerapkannya secara non-iteratif. Tapi itu hanya akan memakan waktu cukup lama sampai hasil yang valid "riak" melalui logika. Implementasi di atas adalah non-iteratif.
Marcus Müller
9
Saya ingin poster dinding pembagi.
Ian Howson
5
Ada PDF sekarang di inti multiply . Ini berukuran 3378 × 3177 mm, jadi silakan diskusikan dengan pasangan Anda sebelum Anda meletakkannya di langit-langit kamar.
Marcus Müller
2
Gambar 100 megapiksel Anda mengesankan, tetapi terlalu berlebihan untuk poin yang Anda coba buat, dan mereka menyebabkan masalah besar bagi siapa pun yang mencoba melihat halaman ini pada perangkat dengan memori terbatas seperti ponsel atau tablet. Jika Anda ingin menampilkan gambar sebaris, temukan cara untuk menghasilkan pratinjau resolusi yang lebih rendah.
Dave Tweed
4
Yo, grafik graphviz itu lolos, yo!
Spencer Williams
8

Pembagian lambat secara inheren berulang sehingga cenderung memakan waktu lebih lama. Ada algoritma pembagian lambat agak lebih cepat daripada yang sederhana, menggunakan tabel pencarian. Algoritma SRT menghasilkan dua bit per siklus. Kesalahan dalam tabel seperti itu adalah penyebab bug PentIV FDIV yang terkenal (sekitar 1994). Lalu ada yang disebut algoritma pembagian cepat.

Tentu saja, pada prinsipnya, Anda cukup menggunakan tabel pencarian besar untuk menghitung produk atau hasil bagi dari dua angka, dan dengan demikian mendapatkan hasil dalam satu siklus tunggal, tetapi itu cenderung dengan cepat menjadi tidak praktis karena jumlah bit per angka meningkat.

Spehro Pefhany
sumber
Tetapi intinya adalah - algoritma pembagian tidak dapat diparalelkan, tidak seperti algoritma multiplikasi, dan itulah mengapa mereka jauh lebih lambat?
Marko Gulin
2
@MarkoGulin "tidak bisa" adalah pernyataan yang sangat kuat. Ini tentu tidak langsung.
Spehro Pefhany
2
Saya pikir Anda bisa melemahkannya dari "algoritma divisi tidak dapat diparalelkan" ke "cara yang kami temukan untuk memaralisasi divisi lebih berat pada perangkat keras yang mengimplementasikan divisi daripada multiplikasi paralel." Sphero memberikan contoh bagaimana melakukan pembagian siklus tunggal menggunakan gerbang O (2 ^ n) untuk melipatgandakan angka n-bit ... tapi itu tidak praktis.
Cort Ammon
1
Divisi panjang dapat memanfaatkan paralelisme ke tingkat yang diinginkan dengan menghitung perkiraan timbal balik yang, ketika dikalikan dengan pembagi, menghasilkan hasil dari bentuk 1000 ... xxxx, Ketika bekerja dengan pembagi dalam bentuk sedemikian rupa dengan N leadig nol, mudah untuk menghitung bit N dari hasil dengan setiap langkah.
supercat
8

Kita dapat memiliki beberapa lapisan logika per siklus clock tetapi ada batasnya, persis berapa banyak layer logika yang dapat kita miliki, seberapa kompleks lapisan tersebut dapat bergantung pada kecepatan clock dan proses semikonduktor kami.

Namun, ada banyak algoritma multiplikasi yang berbeda, dan saya tidak memiliki petunjuk yang mana yang dapat digunakan oleh mikrokontroler

Afaict sebagian besar perkalian di komputer menggunakan varian perkalian panjang biner. Penggandaan panjang biner melibatkan

  • Mengubah satu operan dengan berbagai jumlah yang berbeda
  • Menyembunyikan angka yang digeser berdasarkan operan kedua
  • Menambahkan hasil masking bersama.

Jadi mari kita lihat mengimplementasikan ini dalam perangkat keras.

  • Menggeser hanyalah masalah bagaimana kita menghubungkan semuanya, jadi itu gratis.
  • Masking membutuhkan gerbang AND. Itu berarti satu lapisan logika, jadi dari sudut pandang waktu itu murah.
  • Tambahannya relatif mahal karena kebutuhan untuk membawa rantai. Untungnya ada trik yang bisa kita gunakan. Untuk sebagian besar tahap penambahan daripada menambahkan dua angka untuk menghasilkan satu, kita dapat menambahkan tiga angka untuk menghasilkan dua.

Jadi mari kita masukkan berapa banyak tahapan logika yang kita butuhkan untuk pengganda 8x8 dengan hasil 16 bit. Untuk kesederhanaan mari kita asumsikan kita tidak mencoba dan mengoptimalkan karena fakta bahwa tidak semua hasil antara memiliki bit di semua posisi.

Mari kita asumsikan bahwa penambah penuh diimplementasikan dalam dua "tahap gerbang".

  • 1 untuk masking untuk menghasilkan 8 hasil antara.
  • 2 untuk menambah grup dari tiga angka untuk mengurangi 8 hasil antara menjadi 6
  • 2 untuk menambah grup dari tiga angka untuk mengurangi 6 hasil antara menjadi 4
  • 2 untuk menambahkan kelompok tiga angka untuk mengurangi 4 hasil antara menjadi 3
  • 2 untuk menambahkan kelompok tiga angka untuk mengurangi 3 hasil antara menjadi 2
  • 32 untuk menjumlahkan dua hasil akhir.

Jadi sekitar 46 tahapan logika total. Sebagian besar dari yang dihabiskan menambahkan hingga dua hasil menengah terakhir.

Ini dapat ditingkatkan lebih lanjut dengan mengeksploitasi fakta bahwa tidak semua hasil antara memiliki semua bit yang hadir (yang pada dasarnya adalah apa yang dilakukan pengganda dada), dengan menggunakan carry lookahead adder untuk langkah terakhir. Dengan menambahkan 7 angka untuk menghasilkan 3 bukannya tiga untuk menghasilkan dua (mengurangi jumlah tahap dengan harga lebih banyak gerbang dan gerbang yang lebih luas) dll.

Itu semua detail kecil, poin penting adalah bahwa jumlah tahapan yang diperlukan untuk mengalikan dua bilangan n bit dan menghasilkan hasil 2n bit kira-kira sebanding dengan n.


Di sisi lain jika kita melihat algoritma pembagian kita menemukan mereka semua memiliki proses berulang di mana.

  1. Apa yang dilakukan pada satu iterasi tergantung pada hasil iterasi sebelumnya.
  2. jumlah tahapan logika yang diperlukan untuk mengimplementasikan iterasi kira-kira sebanding dengan n (pengurangan dan perbandingan sangat mirip dalam kerumitan dengan penambahan)
  3. jumlah iterasi juga kira-kira sebanding dengan n.

Jadi jumlah tahapan logika yang diperlukan untuk mengimplementasikan divisi kira-kira sebanding dengan n kuadrat.

Peter Green
sumber
Terima kasih atas jawaban Anda. Saya telah membaca di Wiki bahwa algoritme Dadda sangat efisien dalam hal jumlah gerbang yang diperlukan untuk mengimplementasikan algoritma ini pada perangkat keras. Meskipun begitu, sebagian besar perangkat keras menggunakan "perkalian panjang biner"?
Marko Gulin
1
Saya tlooks seperti algotihm dada adalah versi dioptimalkan dari perkalian panjang biner.
Peter Green
Saya membakar 8 siklus untuk melakukan pembagian 1 / x. Saya kemudian menggunakannya melawan perkalian 8 siklus dengan biaya tetap 16 siklus.
b degnan
Ini menunjukkan dengan baik bahwa perkalian tidak jauh lebih buruk daripada penambahan.
Hagen von Eitzen
1
Iterasi membutuhkan pengurangan yang dapat dilakukan dalam tahap O (lgN) menggunakan perangkat keras O (NlgN), atau tahap O (sqrt (N)) menggunakan perangkat keras O (N). Poin penting, bagaimanapun, adalah bahwa perkalian membutuhkan tahap O (lgN), sedangkan pembagian membutuhkan tahap O (NlgN). Bukan O (N * N) tetapi lebih besar dari perkalian dengan faktor O (N) kecuali seseorang memulai dengan mengambil perkiraan kebalikan untuk memungkinkan lebih banyak pekerjaan yang harus dilakukan per langkah.
supercat
4

Algoritma pembagian (sebenarnya algoritma apa pun) dapat dibuat dalam satu siklus clock. Jika Anda bersedia membayar untuk transistor tambahan dan tarif clock yang diizinkan lebih rendah.

Misalkan Anda memiliki satu set gerbang yang mengimplementasikan satu siklus clock dari algoritma pembagian multi-siklus yang ada. Untuk membuat algoritma siklus tunggal, gunakan beberapa tahap perangkat keras (mirip dengan yang digunakan dalam satu tahap algoritma multi-siklus), dengan output dari satu tahap memberi makan tahap berikutnya.

Tentu saja alasan untuk tidak melakukannya dengan cara itu adalah karena menggunakan banyak transistor. Misalnya untuk divisi 16 bit mungkin menggunakan hampir 16 X lebih banyak transistor. Juga memiliki lebih banyak tahap gerbang menurunkan frekuensi clock maksimum yang diizinkan (karena ada lebih banyak tahap penundaan propagasi).

pengguna4574
sumber
4

Algoritma pembagian praktis semua didasarkan pada suite numerik yang menyatu dengan hasil bagi.

  • Ada metode aditif, seperti non-restore atau SRT yang bekerja dengan menambahkan atau menghapus 2 ^ N ke hasil bagi dan secara bersamaan menambah atau menghapus 2 ^ N * Pembagi ke sisa parsial sampai telah terkonvergensi ke nol.

  • Ada metode multiplikasi, seperti Newton-Raphson atau Goldshmidth, yang merupakan metode pencarian root di mana divisi dihitung sebagai kebalikan dari perkalian.

Metode aditif memberikan satu atau beberapa bit per siklus. Metode multiplikasi menggandakan jumlah bit untuk setiap siklus tetapi membutuhkan beberapa perkiraan awal, sering diperoleh dengan tabel konstan.

Denominasi "lambat" dan "cepat" menyesatkan, karena kecepatan sebenarnya tergantung pada jumlah bit, berapa banyak perangkat keras yang dikhususkan untuk fungsi (dan pengganda cepat sangat besar) ...

Divisi lebih lambat daripada perkalian karena tidak ada metode paralel langsung untuk menghitungnya: Entah ada iterasi, atau perangkat keras disalin untuk mengimplementasikan iterasi sebagai blok bertingkat (atau pipeline).

TEMLIB
sumber
0

Mengapa pembagian perangkat keras memakan waktu lebih lama daripada multiplikasi pada mikrokontroler?

Ini bukan pertanyaan elektronik. Paling-paling itu adalah pertanyaan komputer, lebih baik ditujukan ke Stack Overflow.

Lihat, misalnya, di sini: Apakah multiplikasi lebih cepat daripada pembagian float?

Pada kenyataannya, ini adalah pertanyaan di Kehidupan Nyata: Mengapa pembagian membutuhkan waktu lebih lama daripada multiplikasi?

Mana yang ingin Anda hitung di atas kertas?

51 * 82

atau

4182 / 51

Pembagian membutuhkan waktu lebih lama daripada perkalian karena lebih sulit dilakukan .

Nick Gammon
sumber