เหตุใดการแบ่งฮาร์ดแวร์จึงใช้เวลานานกว่าการคูณ


37

เหตุใดการแบ่งฮาร์ดแวร์จึงใช้เวลานานกว่าการคูณบนไมโครคอนโทรลเลอร์มาก? เช่นใน dsPIC การหารใช้เวลา 19 รอบในขณะที่การคูณจะใช้เวลาหนึ่งรอบนาฬิกา

ฉันผ่านบทเรียนบางอย่างรวมถึงอัลกอริทึมการหารและอัลกอริทึมการคูณใน Wikipedia นี่คือเหตุผลของฉัน

อัลกอริทึมการหารเช่นวิธีการหารช้าพร้อมการเรียกคืนบนวิกิพีเดียเป็นอัลกอริทึมแบบเรียกซ้ำ ซึ่งหมายความว่าผลลัพธ์ (ขั้นกลาง) จากขั้นตอนkจะใช้เป็นอินพุตไปยังขั้นตอนk+1ซึ่งหมายความว่าอัลกอริทึมเหล่านี้ไม่สามารถทำการขนานกันได้ ดังนั้นจึงใช้เวลาอย่างน้อยหนึ่งnรอบในการแบ่งให้เสร็จสมบูรณ์ในขณะที่nมีจำนวนบิตในเงินปันผล สำหรับการจ่ายเงินปันผลแบบ 16 บิตนี่จะเท่ากับอย่างน้อย 16 รอบ

อัลกอริทึมการคูณไม่จำเป็นต้องเรียกซ้ำซึ่งหมายความว่ามันเป็นไปได้ที่จะทำให้มันขนานกัน อย่างไรก็ตามมีอัลกอริทึมการคูณที่แตกต่างกันมากมายและฉันไม่มีเงื่อนงำที่ไมโครคอนโทรลเลอร์อาจใช้ การคูณจะทำงานกับฮาร์ดแวร์ / ไมโครคอนโทรลเลอร์ได้อย่างไร

ฉันได้พบอัลกอริทึมตัวคูณ Daddaซึ่งควรจะใช้เวลาหนึ่งรอบนาฬิกาเพื่อเสร็จสิ้น อย่างไรก็ตามสิ่งที่ฉันไม่ได้รับที่นี่คืออัลกอริทึมของ Dadda ดำเนินการในสามขั้นตอนในขณะที่ผลลัพธ์จากขั้นตอนที่ 1 ถูกนำมาใช้ในขั้นตอนที่ 2 เป็นต้นจากนี้สิ่งนี้จะใช้เวลาอย่างน้อยสามรอบนาฬิกา


2
อัลกอริทึมไม่ได้กำหนดจำนวนรอบสัญญาณนาฬิกาจริงๆ CPU เฉพาะของคุณอาจมีตัวคูณ / ตัวแบ่งฮาร์ดแวร์ทำงานในรอบเดียวหรือ 20 รอบโดยไม่คำนึงถึงการใช้งานภายใน
ยูจีน Sh.

1
OP คุณสามารถให้ลิงค์ที่ให้ข้อมูลเพิ่มเติมเกี่ยวกับรอบ 19 vs 1 ที่คุณพูดถึงได้หรือไม่? มีบางอย่างเกี่ยวกับ DSP ของคุณ
Vladimir Cravero

1
ขอบคุณสำหรับคำตอบ นี่คือแผ่นข้อมูลสำหรับไมโครคอนโทรลเลอร์ฉัน: ww1.microchip.com/downloads/en/DeviceDoc/70005127c.pdf ดูภาพรวมของชุดคำสั่งเริ่มต้นในหน้า 292 มันบอกว่าคำสั่ง DIV ทั้งหมดใช้เวลา 18 รอบในขณะที่คำแนะนำ MUL ทั้งหมดใช้เวลาเพียง 1 รอบ แต่ไม่ธรรมดาสำหรับ MCU นี้เท่านั้นฉันได้เห็นสิ่งนี้ใน MCU อื่น ๆ มากมาย
Marko Gulin

2
@ เครกเอาละพวกเขาเหมือนกันใช่มั้ย สำหรับฉัน ฉันไม่คิดว่ามันแสดงให้เห็นว่าคุณอาจจินตนาการ
TonyM

1
ปัจจัยอื่น ๆ คือเศรษฐศาสตร์และรูปแบบการใช้งาน ประเพณีส่วนใหญ่จะเรียกใช้การคูณทวีมากกว่าการหาร การอุทิศพื้นที่ขนาดใหญ่ของซิลิกอนให้กับฟังก์ชั่นการแบ่งฮาร์ดแวร์ที่เร็วขึ้นซึ่งจะใช้งานไม่บ่อยนักคือเศรษฐศาสตร์ที่ไม่ดี ดีกว่าที่จะทำชิปขนาดเล็กและราคาถูกกว่าหรือใช้ตรรกะพิเศษในลักษณะที่มีประสิทธิผลมากขึ้น BTW เมื่อฉันเริ่มต้นด้วย minicomputers การหารไม่ใช่คำสั่งเสมอ ในบางเครื่องมันเป็นการเรียกไลบรารี่ของซอฟต์แวร์เช่นสแควร์รูท
nigel222

คำตอบ:


34

ตัวแบ่งจะจับคู่กับฮาร์ดแวร์ทั่วไปอย่างงดงามน้อยกว่ามาก ใช้ Lattice ICE40 FPGAs เป็นตัวอย่าง

ให้เราเปรียบเทียบสองกรณี: ตัวคูณ 8x8 นี้เป็น 16 บิต:

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

และตัวแบ่งที่ลดขนาดตัวถูกดำเนินการ 8 และ 8 บิตเป็น 8 บิต:

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

(ใช่ฉันรู้นาฬิกาไม่ได้ทำอะไรเลย)

ภาพรวมของวงจรสร้างขึ้นเมื่อการทำแผนที่คูณไปยัง ICE40 FPGA สามารถพบได้ที่นี่และdivider นี่

สถิติการสังเคราะห์จาก Yosys คือ:

คูณ

  • จำนวนสายไฟ: 155
  • จำนวนบิตลวด: 214
  • จำนวนสายสาธารณะ: 4
  • จำนวนบิตลวดสาธารณะ: 33
  • จำนวนความทรงจำ: 0
  • จำนวนบิตหน่วยความจำ: 0
  • จำนวนกระบวนการ: 0
  • จำนวนเซลล์: 191
    • SB_CARRY 10
    • SB_DFF 16
    • SB_LUT4 165

หาร

  • จำนวนสายไฟ: 145
  • จำนวนบิตลวด: 320
  • จำนวนสายสาธารณะ: 4
  • จำนวนบิตลวดสาธารณะ: 25
  • จำนวนความทรงจำ: 0
  • จำนวนบิตหน่วยความจำ: 0
  • จำนวนกระบวนการ: 0
  • จำนวนเซลล์: 219
    • SB_CARRY 85
    • SB_DFF 8
    • SB_LUT4 126

เป็นที่น่าสังเกตว่าขนาดของ verilog ที่สร้างขึ้นสำหรับตัวคูณแบบเต็มความกว้างและตัวแบ่งการหารที่ใหญ่ที่สุดนั้นไม่มากนัก อย่างไรก็ตามหากคุณดูรูปภาพด้านล่างคุณจะสังเกตเห็นว่าตัวคูณมีความลึก 15 ซึ่งในขณะที่ตัวแบ่งดูเหมือน 50 หรือมากกว่านั้น เส้นทางวิกฤต (เส้นทางที่ยาวที่สุดที่สามารถเกิดขึ้นได้ระหว่างการใช้งาน) เป็นสิ่งที่กำหนดความเร็ว


คุณจะไม่สามารถอ่านสิ่งนี้ได้เพื่อสร้างความประทับใจ ฉันคิดว่าความแตกต่างในความซับซ้อนเป็นไปได้ที่จะเห็น นี่คือตัวคูณ / วงรอบเดียว!

คูณ

ทวีคูณบน ICE40 (คำเตือน: ~ 100 Mpixel image)

ปรับขนาดภาพของตัวคูณ

หาร

( หารด้วย ICE40 ) (คำเตือน: ~ 100 Mpixel image)

รูปภาพที่ปรับสัดส่วนของตัวแบ่ง


4
ไม่คุณสามารถใช้มันได้โดยไม่ต้องทำซ้ำ แต่จะใช้เวลาพอสมควรจนกระทั่งผลลัพธ์ที่ถูกต้อง "ripples" ผ่านตรรกะ การใช้งานด้านบนไม่ใช่การทำซ้ำ
Marcus Müller

9
ฉันต้องการโปสเตอร์ติดผนังของตัวแบ่ง
Ian Howson

5
มีรูปแบบไฟล์ PDF ตอนนี้ในคูณสรุปสาระสำคัญ มันคือ 3378 × 3177 มม. ดังนั้นโปรดพูดคุยกับคนสำคัญของคุณก่อนที่คุณจะวางมันลงบนเพดานห้องนอน
Marcus Müller

2
ภาพ 100 ล้านพิกเซลของคุณนั้นน่าประทับใจ แต่เกินความจริงสำหรับจุดที่คุณพยายามทำและมันก็สร้างปัญหาใหญ่สำหรับทุกคนที่พยายามดูหน้านี้บนอุปกรณ์ที่มีหน่วยความจำ จำกัด เช่นโทรศัพท์หรือแท็บเล็ต หากคุณต้องการแสดงภาพแบบอินไลน์โปรดหาวิธีในการสร้างตัวอย่างความละเอียดที่ต่ำกว่า
Dave Tweed

4
โย่ชาร์ตกราฟวิซเหล่านั้นหลุดไปแล้วคุณ!
Spencer Williams

8

การแบ่งอย่างช้า ๆ ซ้ำแล้วซ้ำอีกจึงมีแนวโน้มที่จะใช้เวลานาน มีอัลกอริธึมการหารที่ช้ากว่าค่อนข้างง่ายกว่าการใช้ตารางการค้นหา อัลกอริทึม SRT สร้างสองบิตต่อรอบ ข้อผิดพลาดในตารางดังกล่าวเป็นสาเหตุของข้อบกพร่อง Pentium FDIV ที่น่าอับอาย(แคลิฟอร์เนียในปี 1994) จากนั้นมีอัลกอริธึมการแบ่งอย่างรวดเร็ว

โดยหลักการแล้วคุณสามารถใช้ตารางการค้นหาขนาดใหญ่เพื่อคำนวณผลิตภัณฑ์หรือความฉลาดของตัวเลขสองจำนวนและทำให้ได้ผลลัพธ์ในรอบเดียว แต่ก็มีแนวโน้มที่จะได้รับอย่างรวดเร็วเมื่อจำนวนบิตต่อจำนวนเพิ่มขึ้นอย่างรวดเร็ว


แต่บรรทัดล่างคือ - อัลกอริธึมการแบ่งไม่สามารถขนานกันได้ซึ่งแตกต่างจากอัลกอริธึมการคูณและนั่นคือสาเหตุที่มันช้ากว่ามาก?
Marko Gulin

2
@ MarkoGulin "ไม่" เป็นคำยืนยันที่แข็งแกร่งมาก มันไม่ตรงไปตรงมาอย่างแน่นอน
Spehro Pefhany

2
ฉันคิดว่าคุณสามารถทำให้มันอ่อนลงจาก "อัลกอริธึมการหารไม่สามารถทำให้ขนานกัน" เป็น "วิธีที่เราพบว่าการแบ่งคู่ขนานนั้นมีความตึงเครียดมากขึ้นในฮาร์ดแวร์ที่ใช้การแบ่งมากกว่าการคูณแบบขนาน สเปโรแสดงตัวอย่างของวิธีการแบ่งรอบเดียวโดยใช้ประตู O (2 ^ n) เพื่อคูณตัวเลข n-bit ... แต่นั่นไม่จริง
Cort Ammon

1
การหารแบบยาวสามารถใช้ประโยชน์จากความเท่าเทียมในระดับใดก็ได้โดยการคำนวณผลตอบแทนโดยประมาณซึ่งเมื่อคูณด้วยตัวหารแล้วผลลัพธ์ของรูปแบบ 1000 ... xxxx เมื่อทำงานกับตัวหารในรูปแบบที่มีเลขศูนย์ N leadig นั้นง่าย เพื่อคำนวณ N บิตของผลลัพธ์ในแต่ละขั้นตอน
supercat

8

เราสามารถมีตรรกะได้หลายเลเยอร์ต่อรอบสัญญาณนาฬิกา แต่มีข้อ จำกัด จำนวนตรรกะที่เราสามารถมีความซับซ้อนของเลเยอร์เหล่านั้นจะขึ้นอยู่กับความเร็วสัญญาณนาฬิกาและกระบวนการเซมิคอนดักเตอร์ของเรา

อย่างไรก็ตามมีอัลกอริทึมการคูณที่แตกต่างกันมากมายและฉันไม่มีเงื่อนงำที่ไมโครคอนโทรลเลอร์อาจใช้

Afaict การคูณส่วนใหญ่ในคอมพิวเตอร์ใช้ตัวแปรของการคูณยาวแบบไบนารี การคูณแบบยาวไบนารีเกี่ยวข้อง

  • เลื่อนหนึ่งตัวถูกดำเนินการด้วยกระสุนที่แตกต่างกัน
  • ปิดบังตัวเลขที่ถูกเลื่อนตามตัวถูกดำเนินการที่สอง
  • การเพิ่มผลลัพธ์ของการมาสก์เข้าด้วยกัน

ดังนั้นให้ดูที่การใช้สิ่งนี้ในฮาร์ดแวร์

  • การเลื่อนลอยเป็นเพียงเรื่องของวิธีที่เราเชื่อมโยงสิ่งต่างๆเข้าด้วยกันดังนั้นมันจึงฟรี
  • กาวต้องใช้และประตู นั่นหมายถึงตรรกะหนึ่งเลเยอร์ดังนั้นจากมุมมองเวลาราคาถูก
  • นอกจากนี้ยังมีราคาค่อนข้างแพงเนื่องจากความต้องการโซ่พกพา โชคดีที่มีกลอุบายที่เราสามารถใช้ได้ สำหรับขั้นตอนการบวกส่วนใหญ่แทนที่จะเพิ่มตัวเลขสองตัวเพื่อสร้างหนึ่งเราสามารถเพิ่มตัวเลขสามตัวเพื่อสร้างสอง

เพื่อให้ ballpark มีจำนวนสเตจตรรกะที่เราต้องการสำหรับตัวคูณ 8x8 พร้อมผลลัพธ์ 16 บิต สำหรับความเรียบง่ายสมมติว่าเราไม่ลองและปรับให้เหมาะสมสำหรับความจริงที่ว่าผลลัพธ์กลางทั้งหมดไม่ได้มีบิตในทุกตำแหน่ง

สมมติว่า adder แบบเต็มถูกนำมาใช้ในสอง "ระยะประตู"

  • 1 สำหรับการปิดบังเพื่อสร้างผลลัพธ์ระดับกลาง 8 รายการ
  • 2 เพื่อเพิ่มกลุ่มของตัวเลขสามตัวเพื่อลดผลลัพธ์กลาง 8 รายการเป็น 6
  • 2 เพื่อเพิ่มกลุ่มของตัวเลขสามตัวเพื่อลดผลลัพธ์กลาง 6 ถึง 4
  • 2 เพื่อเพิ่มกลุ่มของตัวเลขสามตัวเพื่อลดผลลัพธ์กลาง 4 เป็น 3
  • 2 เพื่อเพิ่มกลุ่มของตัวเลขสามตัวเพื่อลดผลลัพธ์กลาง 3 เป็น 2
  • 32 เพื่อเพิ่มผลลัพธ์สองรายการสุดท้าย

ดังนั้นตรรกะประมาณ 46 สเตจรวม ส่วนใหญ่จะใช้ในการเพิ่มผลกลางสองครั้งสุดท้าย

สิ่งนี้สามารถปรับปรุงให้ดียิ่งขึ้นได้โดยการใช้ประโยชน์จากความจริงที่ว่าผลลัพธ์กลางทั้งหมดไม่ได้มีบิตทั้งหมดอยู่ (นั่นคือสิ่งที่ตัวคูณ Dada ทำ) โดยใช้ตัวบวกพกพา lookahead สำหรับขั้นตอนสุดท้าย โดยการเพิ่มหมายเลข 7 เพื่อผลิต 3 แทนสามเพื่อสร้างสอง (ลดจำนวนของขั้นตอนที่ราคาของประตูเพิ่มเติมและประตูที่กว้างขึ้น) เป็นต้น

นั่นคือรายละเอียดเล็กน้อยทั้งหมดประเด็นสำคัญคือจำนวนขั้นตอนที่จำเป็นในการคูณตัวเลขสองบิตและสร้างผลลัพธ์บิตที่ 2 คือสัดส่วนโดยประมาณกับ n


ในทางกลับกันถ้าเราดูอัลกอริธึมการหารเราพบว่าพวกมันทั้งหมดมีกระบวนการวนซ้ำอยู่ที่ไหน

  1. สิ่งที่ทำในการทำซ้ำหนึ่งครั้งขึ้นอยู่กับผลลัพธ์ของการทำซ้ำครั้งก่อนหน้าอย่างหนัก
  2. จำนวนขั้นตอนตรรกะที่จำเป็นในการทำให้เกิดการวนซ้ำนั้นเป็นแบบประมาณไปที่ n (การลบและการเปรียบเทียบนั้นคล้ายคลึงกันมากในความซับซ้อนที่จะเพิ่ม)
  3. จำนวนการวนซ้ำยังเป็นสัดส่วนกับ n

ดังนั้นจำนวนของสเตจลอจิกที่ต้องใช้ในการแบ่งเป็นสัดส่วนประมาณ n กำลังสอง


ขอบคุณสำหรับคำตอบ. ฉันได้อ่าน Wiki ว่าอัลกอริทึมของ Dadda นั้นมีประสิทธิภาพมากเมื่อพูดถึงจำนวนประตูที่ต้องการเพื่อใช้อัลกอริทึมนี้กับฮาร์ดแวร์ แม้จะเป็นเช่นนั้นฮาร์ดแวร์ส่วนใหญ่ใช้ "การคูณแบบยาวไบนารี" หรือไม่?
Marko Gulin

1
ฉันดูเหมือนว่า algotihm ของ Dada เป็นรุ่นที่เหมาะที่สุดของการคูณแบบยาวไบนารี
ปีเตอร์กรีน

ฉันเผา 8 รอบเพื่อทำหาร 1 / x ฉันจะใช้มันกับการคูณ 8 รอบสำหรับค่าใช้จ่ายคงที่ที่ 16 รอบ
b degnan

นี่แสดงให้เห็นอย่างชัดเจนว่าการคูณนั้นไม่ได้เลวร้ายยิ่งไปกว่านั้น
Hagen von Eitzen

1
การวนซ้ำต้องใช้การลบซึ่งสามารถทำได้ในขั้นตอน O (lgN) โดยใช้ฮาร์ดแวร์ O (NlgN) หรือ O (sqrt (N)) ขั้นตอนโดยใช้ฮาร์ดแวร์ O (N) แม้ว่าจุดสำคัญคือการคูณนั้นต้องใช้ระยะ O (lgN) ในขณะที่การแบ่งต้องใช้ขั้นตอน O (NlgN) ไม่ใช่ O (N * N) แต่มีขนาดใหญ่กว่าการคูณด้วยปัจจัยของ O (N) เว้นแต่ว่าจะเริ่มต้นด้วยการแลกเปลี่ยนซึ่งกันและกันโดยประมาณเพื่อให้สามารถทำงานได้มากขึ้นต่อขั้นตอน
supercat

4

อัลกอริทึมการหาร (อันที่จริงอัลกอริทึมใด ๆ ) สามารถทำได้ในรอบนาฬิกาหนึ่ง หากคุณยินดีจ่ายค่าทรานซิสเตอร์เพิ่มเติมและลดอัตรานาฬิกาที่ได้รับอนุญาต

สมมติว่าคุณมีชุดของเกทที่ใช้หนึ่งรอบสัญญาณนาฬิกาของอัลกอริทึมการหารแบบหลายรอบที่มีอยู่ ในการทำให้อัลกอริทึมรอบเดียวใช้ฮาร์ดแวร์หลายขั้นตอน (คล้ายกับที่ใช้ในขั้นตอนหนึ่งของอัลกอริธึมหลายรอบ) ด้วยเอาต์พุตของขั้นตอนเดียวที่ป้อนในระยะถัดไป

แน่นอนว่าเหตุผลที่จะไม่ทำอย่างนั้นคือมันใช้ทรานซิสเตอร์จำนวนมาก ตัวอย่างเช่นการแบ่ง 16 บิตมันอาจใช้ทรานซิสเตอร์มากกว่า 16 X นอกจากนี้การมีประตูมากขึ้นช่วยลดความถี่สัญญาณนาฬิกาที่อนุญาตสูงสุด (เนื่องจากมีการล่าช้าในการแพร่กระจายมากขึ้น)


4

อัลกอริทึมการหารเชิงปฏิบัติทั้งหมดขึ้นอยู่กับชุดตัวเลขซึ่งรวมกันเป็นผลหาร

  • มีวิธีการเพิ่มเติมเช่นการไม่คืนค่าหรือ SRT ซึ่งทำงานโดยการเพิ่มหรือลบ 2 ^ N ให้กับความฉลาดทางและเพิ่มหรือลบตัวหาร 2 ^ N * ไปยังส่วนที่เหลือจนกว่ามันจะกลายเป็นศูนย์

  • มีวิธีการคูณเช่น Newton-Raphson หรือ Goldshmidth ซึ่งเป็นวิธีการค้นหารากที่การหารถูกคำนวณเป็นส่วนผกผันของการคูณ

วิธีการเติมให้หนึ่งหรือสองสามบิตต่อรอบ วิธีการคูณสองเท่าของจำนวนบิตสำหรับแต่ละรอบ แต่ต้องมีการประมาณค่าเริ่มต้นบางอย่างซึ่งมักได้จากตารางคงที่

"ช้า" และ "เร็ว" ได้แก่ ความเข้าใจผิดเนื่องจากความเร็วที่แท้จริงขึ้นอยู่กับจำนวนบิตฮาร์ดแวร์ที่ทุ่มเทให้กับฟังก์ชั่น (และตัวคูณเร็วมีขนาดใหญ่มาก) ...

การหารนั้นช้ากว่าการคูณเนื่องจากไม่มีวิธีการแบบขนานโดยตรงสำหรับการคำนวณ: อาจมีการวนซ้ำหรือฮาร์ดแวร์ถูกคัดลอกเพื่อใช้การทำซ้ำเป็นบล็อกที่เรียงซ้อนกัน (หรือไพพ์ไลน์)


0

เหตุใดการแบ่งฮาร์ดแวร์จึงใช้เวลานานกว่าการคูณบนไมโครคอนโทรลเลอร์มาก?

นี่ไม่ใช่คำถามอิเล็กทรอนิกส์ ที่ดีที่สุดคือคำถามคอมพิวเตอร์ดีกว่าจ่าหน้าถึงกองซ้อนมากเกินไป

ดูตัวอย่างที่นี่: การคูณเร็วกว่าการหารลอยหรือไม่

ในความเป็นจริงมันเป็นคำถามชีวิตจริง: เหตุใดการแบ่งใช้เวลานานกว่าการคูณมาก

คุณต้องการคำนวณบนกระดาษแบบไหน

51 * 82

หรือ

4182 / 51

ส่วนที่ใช้เวลานานกว่าการคูณเพราะมันเป็นเรื่องยากที่จะทำ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.