Pentium มีวงจรเฉพาะทางที่ซับซ้อนสำหรับคูณด้วย 3
(righto.com)- ในปี 1993 Intel Pentium มีวงจรเฉพาะ ×3 สำหรับสร้างค่า 3 เท่าเพื่อเร่งการคูณเลขทศนิยมลอยตัว และวงจรเล็ก ๆ นี้เพียงอย่างเดียวก็ใช้ทรานซิสเตอร์หลายพันตัว
- Pentium ใช้ การคูณแบบ radix-8 เพื่อลดจำนวนพจน์ที่ต้องบวกในงานคูณ 64 บิตจาก 64 พจน์เหลือ 22 พจน์ แต่แนวทางนี้จำเป็นต้องสร้างพหุคูณ ×3 ได้อย่างรวดเร็ว
- แม้การคำนวณ ×3 เองจะเป็นเพียงการบวก
x + 2xแต่เพราะขั้นตอนการคูณส่วนที่เหลือต้องรอผลลัพธ์นี้ จึงต้องใช้เทคนิคตัวบวกความเร็วสูงอย่าง carry lookahead และ Kogge-Stone - วงจรนี้เป็นโครงสร้างแบบลำดับชั้นที่รวมบล็อกขนาด 8 บิต 8 ชุดเข้ากับ lookahead ระดับบน และเอาต์พุตจริงถูกขยายเป็น 69 บิต เพื่อรองรับ overflow และการปัดเศษ
- การที่วงจร ×3 เพียงตัวเดียวใช้ทรานซิสเตอร์ราว 9000 ตัว แสดงให้เห็นว่าในยุค Pentium มีการทุ่มฮาร์ดแวร์ออปติไมซ์ที่ซับซ้อนมากเพียงใดเพื่อแลกกับประสิทธิภาพ
ทำไม Pentium ถึงแยกวงจร ×3 ออกมาต่างหาก
- ตัวคูณเลขทศนิยมลอยตัว ของ Pentium คูณเลข 64 บิตสองจำนวนด้วยวิธี radix-8
- การคูณเลขฐานสองแบบทั่วไปจะบวก 0 หรือจำนวนที่ถูกคูณตามแต่ละบิต ดังนั้นการคูณ 64 บิตจึงต้องใช้ 64 พจน์
- วิธี radix-8 จะจัดกลุ่มบิตของตัวคูณครั้งละ 3 บิตเพื่อคูณด้วยค่าใดค่าหนึ่งระหว่าง 0~7 ทำให้จำนวนพจน์ที่ต้องบวกลดเหลือ 22 พจน์
- พหุคูณบางค่าในช่วง 0~7 สร้างด้วยฮาร์ดแวร์ได้ค่อนข้างง่าย
- ×2 ทำได้ด้วยการเลื่อนซ้าย 1 บิต
- ×4 ทำได้ด้วยการเลื่อนซ้าย 2 บิต
- ×6 และ ×7 สามารถจัดการได้ด้วย อัลกอริทึมการคูณแบบ Booth โดยผสาน +1 ของหลัก radix-8 ถัดไปเข้ากับการลบของหลักปัจจุบัน
- ×5 สามารถได้มาจากการนำ ×8 ลบด้วย ×3
- สุดท้ายแล้วพหุคูณที่ยุ่งยากคือ ×3 และ Pentium ก็แก้ปัญหานี้ด้วยวงจรเฉพาะภายในตัวคูณเลขทศนิยมลอยตัว
จุดที่การบวกธรรมดากลายเป็นคอขวด
- ค่าที่คูณ 3 สามารถสร้างได้โดยนำค่าขาเข้ามาบวกกับค่าขาเข้าที่เลื่อนซ้าย 1 บิต
- หากดูเฉพาะโครงสร้าง มันคือการบวก
x + 2x
- หากดูเฉพาะโครงสร้าง มันคือการบวก
- คอขวดเกิดขึ้นที่การ แพร่ carry ระหว่างกระบวนการบวก
- ตัวบวกแบบ ripple-carry ต้องรอให้ carry ที่เกิดจากบิตล่างส่งต่อขึ้นไปยังบิตบนตามลำดับ
- ก่อนที่ผลลัพธ์ ×3 จะพร้อม กระบวนการคูณส่วนที่เหลือก็เริ่มไม่ได้ จึงต้องลดดีเลย์นี้ให้มากที่สุด
- Pentium ใช้ carry-lookahead adder เพื่อคำนวณ carry แบบขนานแทนการส่งต่อทีละขั้น
- แต่ละบิตจะสร้างสัญญาณ carry generate และ carry propagate
- generate แสดงว่าตำแหน่งนั้นสร้าง carry ขึ้นมาเอง
- propagate แสดงว่า carry ที่เข้ามาจะถูกส่งต่อออกไป
- เมื่อคำนวณ carry แบบขนานได้แล้ว ก็สามารถคำนวณบิตผลรวมแบบขนานได้เช่นกัน
Kogge-Stone และ carry lookahead สองชั้น
- หากทำ carry lookahead แบบตรงไปตรงมาทั้งหมด เมื่อจำนวนบิตเพิ่มขึ้น ภาระของวงจรและการเดินสายก็จะสูงขึ้นมาก
- ยิ่งตำแหน่งบิตสูงขึ้น ลอจิกก็ยิ่งซับซ้อน
- เกตที่มีอินพุตจำนวนมากจะช้าลงด้วยเหตุผลทางไฟฟ้า
- Pentium ใช้ ตัวบวกแบบ parallel-prefix Kogge-Stone ในหน่วย 8 บิต
- Kogge-Stone จะรวมสัญญาณ propagate/generate เป็นช่วง ๆ เพื่อคำนวณ carry แบบขนาน
- มันนำผลลัพธ์ระหว่างทางกลับมาใช้ซ้ำเพื่อควบคุมทั้งดีเลย์และขนาดวงจร
- แทนที่จะใช้ Kogge-Stone ชุดเดียวกับข้อมูลทั้ง 64 บิต Pentium แบ่งเป็น โครงสร้างลำดับชั้น 2 ชั้น
- ชั้นล่างใช้วงจร Kogge-Stone ขนาด 8 บิตจำนวน 8 ชุดเพื่อคำนวณ carry ภายในแต่ละบล็อก
- ชั้นบนมองแต่ละบล็อก 8 บิตเป็นหนึ่งหน่วย แล้วคำนวณ carry ระหว่างบล็อก
- เมื่อรวมสองชั้นเข้าด้วยกัน ก็สามารถให้ carry ที่จำเป็นต่อผลรวม 64 บิตได้อย่างรวดเร็ว
- แม้ว่าวงจรจะมองได้ว่าเป็นของ 64 บิต แต่ในทางปฏิบัติเอาต์พุตถูกขยายเป็น 69 บิต โดยมีบิตสำรองสำหรับป้องกัน overflow และใช้ในการปัดเศษ
ลดเวลารอด้วย carry-select
- แต่ละบล็อก 8 บิตมี carry-select adder อยู่ภายใน
- มันจะคำนวณผลรวมล่วงหน้าทั้งกรณีที่ carry-in เป็น 0 และเป็น 1
- เมื่อวงจร lookahead ระดับบนบอกค่า carry-in ที่แท้จริงแล้ว มัลติเพล็กเซอร์จะเลือกผลลัพธ์ที่ถูกต้อง
- วิธีนี้แลกการใช้ฮาร์ดแวร์เพิ่มกับการประหยัดเวลา
- ต้องมีตัวบวกสองชุดและมัลติเพล็กเซอร์สำหรับเลือกผลลัพธ์
- การคำนวณผลรวมและ carry ซ้อนทับกันได้ จึงลดดีเลย์รวมลง
- บล็อก 8 บิตล่างสุดไม่มี carry-in จึงไม่ต้องใช้วงจร carry-select
- บิตเอาต์พุตของบล็อกนี้คำนวณด้วย เกต XNOR
สิ่งที่เกิดขึ้นภายในบล็อก 8 บิต
- แต่ละบล็อก 8 บิตของวงจร ×3 จะแยกสายอินพุตไปยังตัวบวกด้านซ้ายและเส้นทางด้านขวา
- โครงสร้างการแยกนี้ทำให้การบวกค่าขาเข้ากับค่าขาเข้าที่เลื่อนซ้าย 1 บิตกลายเป็นการคูณ ×3
- ด้านบนของบล็อกประกอบด้วยวงจรสำหรับสร้างสัญญาณ propagate/generate
- สัญญาณเหล่านี้จะเข้าสู่วงจร lookahead แบบ Kogge-Stone ขนาด 8 บิต
- ส่วน Kogge-Stone มีความซับซ้อนต่างกันไปตามตำแหน่งบิต จึงไม่ได้ดูเป็นบล็อกซ้ำ ๆ ที่สม่ำเสมอ แต่มีลักษณะไม่เป็นระเบียบ
- ด้านล่างของบล็อกคือพื้นที่ของ carry-select adder
- มันคำนวณผลรวมสองชุดล่วงหน้า แล้วให้มัลติเพล็กเซอร์เลือกตามค่า carry-in
- บล็อก carry-select adder ถูกวางให้แคบกว่าวงจรรอบข้าง เพื่อเว้นพื้นที่ให้บางส่วนของวงจร Kogge-Stone ชั้นบน
- แต่ละบล็อกจะขยายสัญญาณเอาต์พุตด้วย วงจรไดรเวอร์ ก่อนส่งบิตผลลัพธ์ไปยังวงจรตัวคูณถัดไป
เกต XNOR และการติดตั้งระดับทรานซิสเตอร์
- เกต XNOR ในบริเวณบิตล่างของ Pentium ถูกติดตั้งในรูปของ มัลติเพล็กเซอร์
- Intel 386 ใช้เกต AND-NOR สำหรับ XOR และ Z-80 ใช้ pass transistor แต่แนวทางของ Pentium แตกต่างออกไป
- วงจร XNOR นี้ประกอบด้วยอินเวอร์เตอร์สี่ตัวและมัลติเพล็กเซอร์แบบ pass transistor
- อินพุต B จะเลือกที่อินพุตสองทางของมัลติเพล็กเซอร์ว่าจะใช้ค่า A หรือค่า A ที่กลับสัญญาณแล้ว
- ผลลัพธ์ที่ได้จึงเป็นฟังก์ชัน XNOR
- ในการวิเคราะห์ภาพชิป มีการลบชั้นโลหะสองชั้นบนออกเพื่อสังเกตชั้นโลหะล่าง M1 และบริเวณซิลิคอนที่โดปแล้ว
- จุดที่เส้นโพลีซิลิคอนพาดผ่านซิลิคอนที่โดปไว้จะกลายเป็นเกตของทรานซิสเตอร์
- วงจร CMOS ประกอบด้วยทรานซิสเตอร์ NMOS ด้านบนและ PMOS ด้านล่าง
ไดรเวอร์เอาต์พุตแบบ BiCMOS
- เอาต์พุตของวงจร ×3 ต้องการ กระแสสูง
- สัญญาณ ×3 แต่ละเส้นอาจต้องขับได้ถึง 22 พจน์ภายในตัวคูณเลขทศนิยมลอยตัว
- วงจรปลายทางอาจอยู่ไกลจากวงจร ×3 บนชิป
- เพราะมีทั้งสายสัญญาณยาวและเกตทรานซิสเตอร์จำนวนมาก ค่าคาปาซิแตนซ์จึงสูง และการเปลี่ยนสัญญาณให้เร็วต้องใช้กระแสขนาดใหญ่
- Pentium ใช้กระบวนการผลิตแบบ BiCMOS ที่รวม bipolar transistor และ CMOS ไว้บนชิปเดียวกัน
- Pentium ใช้วงจร BiCMOS อย่างกว้างขวางเพื่อลดดีเลย์ของสัญญาณได้สูงสุด 35%
- Intel ยังใช้ BiCMOS กับ Pentium Pro, Pentium II, Pentium III และ Xeon ด้วย
- เมื่อแรงดันไฟของชิปลดลง ข้อดีของ bipolar transistor ก็ลดลง ทำให้ท้ายที่สุด BiCMOS เลิกถูกใช้งาน
- ไดรเวอร์ของวงจร ×3 มีโครงสร้างที่ไดรเวอร์ BiCMOS ตัวหนึ่งไปขับไดรเวอร์ BiCMOS ตัวที่สองอีกที
- เนื่องจากเกตทรานซิสเตอร์ของอินเวอร์เตอร์กระแสสูงมีขนาดใหญ่ จึงต้องมีขั้นกลางมาช่วยขับ
- การค่อย ๆ ขยายสัญญาณขนาดเล็กผ่านหลายขั้นช่วยลดดีเลย์รวมได้
- ทรานซิสเตอร์ NPN ของไดรเวอร์ BiCMOS จะเห็นเป็นรูปกล่องขนาดใหญ่ ต่างจากทรานซิสเตอร์ MOS ทั่วไป
- อินเวอร์เตอร์ใช้โครงสร้าง CMOS มาตรฐาน โดย PMOS ใช้ดันเอาต์พุตให้สูง และ NMOS ใช้ดึงเอาต์พุตให้ต่ำ
- อินเวอร์เตอร์บางตัวถูกออกแบบให้มีคุณสมบัติกระแสไม่สมมาตร เพื่อให้ได้เอาต์พุต high ที่แรงเป็นพิเศษ หรือ low ที่แรงเป็นพิเศษ
ฮาร์ดแวร์คูณสะท้อนความซับซ้อนที่เพิ่มขึ้นอย่างไร
- ประวัติของฮาร์ดแวร์คูณในคอมพิวเตอร์ย้อนกลับไปได้ถึงทศวรรษ 1950
- เทคนิคการคูณแบบ Booth ถูกอธิบายไว้ในปี 1951
- ตัวคูณแบบขนานถูกเสนอในช่วงกลางทศวรรษ 1960 โดย Wallace และ Dadda
- ไมโครโปรเซสเซอร์ยุคแรกมีการรองรับการคูณด้วยฮาร์ดแวร์อย่างจำกัด
- โปรเซสเซอร์อย่าง 6502 ไม่มีฮาร์ดแวร์คูณ ผู้ใช้จึงต้องเขียนแบบซอฟต์แวร์ด้วยการเลื่อนบิตและบวกเอง
- Intel 8086 ใช้ไมโครโค้ดรันลูป shift-and-add ที่ช้า
- 386 มี multiply unit แต่คำสั่งคูณยังใช้เวลาสูงสุด 41 clock cycle
- เมื่อถึงยุค Pentium ชิปสามารถบรรจุทรานซิสเตอร์ได้หลายล้านตัว ทำให้สามารถใส่การออปติไมซ์ประสิทธิภาพที่ซับซ้อนยิ่งขึ้นได้
- การคูณเลขทศนิยมลอยตัวของ Pentium ใช้เวลา 3 clock cycle และวงจรคูณถูกใช้งานอยู่ 2 cycle ในจำนวนนั้น
- การคูณจำนวนเต็ม
MULช้ากว่ามากที่ 11 cycle - ไมโครสถาปัตยกรรม Nehalem ในปี 2008 ลดเวลาคูณเลขทศนิยมลอยตัวลงเหลือ 1 cycle
- ตัวคูณ ×3 ของ Pentium มีทรานซิสเตอร์ประมาณ 9000 ตัว
- นั่นมากกว่าทรานซิสเตอร์ทั้งหมดของไมโครโปรเซสเซอร์ Z80 ในปี 1976 เล็กน้อย
- และวงจร ×3 ก็ยังเป็นเพียงส่วนเล็ก ๆ ของตัวคูณเลขทศนิยมลอยตัวภายในหน่วยประมวลผลเลขทศนิยมของ Pentium เท่านั้น
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
อาจจะนอกเรื่องอยู่มาก แต่เมื่อนานมาแล้วตอนทำงานเกี่ยวกับ การจำลองคอมพิวเตอร์ฐานสาม ผมเคยใช้กลเม็ดน่ารัก ๆ เพื่อหาการแปลงรูปปิดที่เปลี่ยนการหารด้วยกำลังของ 3 ให้เป็นอนุกรมของการเลื่อนบิตและการบวก
ก่อนอื่นให้ดูว่า
1/3 - 1/2 = 2/6 - 3/6หรือก็คือ1/3 = 1/2 - 1/2 (1/3)ถ้าแทนสมการนี้ซ้ำไปเรื่อย ๆ ทางด้านขวา จะได้รูป
1/3 = -(-1/2)^NโดยNอยู่ในช่วง1..infทำแบบคล้ายกันได้ในฐานอื่น ๆ ด้วย ไม่ใช่แค่คู่กำลังของ 2 กับ 3
ความหมายคือ สำหรับค่าที่อยู่ใกล้กำลังของ 2 เราสามารถสร้าง วงจรหารด้วยค่าคงที่แบบเวลาคงที่ ได้ค่อนข้างง่ายโดยใช้แค่ตัวบวกและตัวลบ
โปรเซสเซอร์เกมอาร์เคดของ Cinematronics มี accumulator 12 บิต อยู่สองตัว
คำสั่งคูณจะเลื่อนทั้งคู่ไปทางขวาเหมือนเป็นค่า 24 บิตค่าเดียว และถ้าบิตต่ำสุดออกมาเป็น 1 ก็จะบวกค่าจากหน่วยความจำเข้าไป
ดังนั้นจึงล้างครึ่งบน โหลดค่าหนึ่งไว้ในครึ่งล่าง และผมจำไม่ได้แล้วว่าตั้งค่าแอดเดรสหน่วยความจำของตัวถูกดำเนินการอีกตัวอย่างไร จากนั้นก็สั่งคูณ 1 บิตต่อเนื่องกันหลายครั้ง
วิธีนี้ทำให้ได้ผลคูณ 24 บิต แต่โค้ดส่วนใหญ่ที่ผมเห็นมักเรียกคำสั่งคูณต่อกัน 8 ครั้ง และการใช้งานที่พบบ่อยที่สุดคือ การคูณเมทริกซ์ 2x2 เพื่อหมุนพิกัดของออบเจ็กต์ในเกม
มันสร้างจากชิ้นส่วน 7400 series สำเร็จรูปช่วงกลางทศวรรษ 1970 และมี throughput สูงสุด 5MIPS
ในช่วง 20 ปีที่ผ่านมา ผมมีบางครั้งที่ต้องทำ fixed-point arithmetic และมันทำให้ผมยิ่งเคารพโปรแกรมเมอร์รุ่นก่อนมากขึ้น
เสริมตรงที่บทความบอกว่าคุณอาจเคยได้ยินเทคนิคอย่าง
carry lookahead,Kogge-Stone additionตรงนี้ Kogge คือ Peter Koggeเขาทำงานปริญญาเอกที่ Stanford เคยทำงานเกี่ยวกับกระสวยอวกาศ เป็น IBM Fellow และเป็นผู้ประดิษฐ์ CPU แบบมัลติคอร์ตัวแรก
“CPU แบบมัลติคอร์” เอง ถ้าพูดอย่างเคร่งครัดเป็นไอเดียมากกว่าสิ่งประดิษฐ์ชิ้นเดียว และเมื่อถึงจุดหนึ่งในประวัติศาสตร์เซมิคอนดักเตอร์ มันก็เป็นไอเดียที่ค่อนข้างชัดเจนและธรรมดาด้วย
การทำให้ CPU แบบมัลติคอร์ทำงานได้จริงไม่ใช่เรื่องง่าย แต่สิ่งนั้นก็ไม่ใช่สิ่งประดิษฐ์เดี่ยวเช่นกัน และ ณ ตอนนั้นทีมพัฒนาก็ใหญ่จนการบอกว่าคนคนเดียวแก้ปัญหาทุกอย่างได้เองออกจะเป็นการดูหมิ่นด้วยซ้ำ
Kogge อาจเป็นผู้นำการพัฒนา CPU แบบมัลติคอร์ตัวแรก และอาจเป็นผู้บุกเบิกที่ผลักดันก่อนที่คนอื่นจะมองว่าเป็นไปได้ แต่ไม่ว่าอย่างไรเขาก็ไม่ได้ประดิษฐ์มันขึ้นมาคนเดียว
แนวทางนี้โน้มน้าวได้ในเชิงความคิดพอสมควร ถ้าการย้ายข้อมูลไปยังศูนย์คอมพิวติ้งมี latency หรือต้นทุน ก็ถือว่าสมเหตุสมผล และในกรณีของเราเป็นเซนเซอร์บนอวกาศ จึงสร้างเหตุผลแบบนั้นได้
อย่างไรก็ตาม เท่าที่ผมรู้ วิธีประมวลผลแบบนี้ไม่เคยถูกนำไปใช้ในระบบประมวลผลบนอวกาศอย่างเป็นระบบ แม้หลายระบบอย่างเรดาร์จะทำการลดทอนข้อมูลแบบเฉพาะกิจด้วยฮาร์ดแวร์ใกล้เซนเซอร์ก็ตาม
ขอบคุณที่บอกความเชื่อมโยงนี้
ผมเป็นผู้เขียน ถ้ามีคำถามจะตอบให้
x4ไปลบออกจากx7เพื่อให้ได้x3ไม่ได้?เหมือนมีบางอย่างตกหล่นไป
ถ้า ×2 คำนวณได้ง่ายพอจะใช้ 6x = 8x - 2x ได้ และ ×4 ก็ง่ายเพราะ 4x = 4x ผมก็ไม่เข้าใจว่าทำไมการคำนวณ 3x เป็นผลบวกของ 2x + 1x หรือผลต่างของ 4x - 1x ถึงยากกว่านั้น
อีกอย่าง ถ้าคำนวณ ×6 ได้ง่ายไม่ว่าจะด้วยวิธีใด ทำไมถึงเลื่อนไปทางขวาเพื่อทำให้เป็น ×3 ไม่ได้ แม้จะเป็นขั้นตอนเพิ่ม แต่ขั้นตอนที่เพิ่มนั้นก็เป็นแค่การ shift
แต่ละพจน์ต้องคำนวณได้ง่ายมาก ดังนั้นเพื่อให้ได้พจน์ เราอาจ shift หรือกลับเครื่องหมายได้ แต่ทำการบวกอีกครั้งไม่ได้
ประเด็นสำคัญคือ ถ้าคำนวณ ×3 ไว้ล่วงหน้าหนึ่งครั้ง ก็สามารถนำไปใส่ในพจน์ใดก็ได้จาก 22 พจน์ที่ต้องใช้หลังจากนั้น
เราไม่สามารถใส่ ×2 กับ ×1 ลงในพจน์เพื่อทำเป็น ×3 ได้ เพราะถ้าทำแบบนั้นจะต้องมีตัวบวกอีกตัวสำหรับทุกพจน์
กล่าวอีกอย่าง สิ่งที่ต้องการคือ วงจรคำนวณ ×3 หนึ่งวงจร ไม่ใช่วงจร 22 ชุด
สำหรับคำถามเรื่อง ×6 ค่านี้คำนวณโดยใส่ ×2 ที่เป็นลบลงในพจน์ และในเชิงแนวคิดบวก 1 ให้ตัวเลขหลักถัดไปเพื่อให้ได้ ×8 ค่า ×8 นี้เป็นส่วนหนึ่งของพจน์คนละตัวกันโดยสิ้นเชิง จึงเลื่อนไปทางขวาไม่ได้
ตัวเลขกับผลรวมสลับไปมามากจนซับซ้อน แต่ถ้ามองแบบนี้น่าจะสมเหตุสมผล
การคูณด้วย 3 เท่า เป็นการดำเนินการที่พบได้บ่อยจริง ๆ โดยเฉพาะในการคำนวณที่อยู่ มักมีกรณีที่คูณดัชนีด้วย 3 ผ่านการเลื่อนบิตและการบวก
ถ้าอิมพลีเมนต์แบบตรงไปตรงมา เวลาแฝงจะเพิ่มขึ้นพอสมควร แต่ถ้าใช้วงจรนี้ คำสั่ง LEA (Load Effective Address) ก็ประมวลผลได้ในหนึ่งไซเคิล ดังนั้นการใช้ทรานซิสเตอร์ในระดับนั้นกับตรงนี้จึงเป็นทางเลือกที่ดีพอแล้ว
LEA เป็นเพียงคำสั่งที่นำที่อยู่ซึ่งคำนวณได้จากโหมดการกำหนดที่อยู่ ไปใส่ในโอเปอแรนด์เอาต์พุต แทนที่จะย้ายข้อมูลจากที่อยู่นั้น และการคำนวณที่อยู่ที่ LEA ทำได้ คำสั่ง MOV ก็ทำได้ทั้งหมดเช่นกัน
โหมดการกำหนดที่อยู่แบบอินเด็กซ์ที่ MOV หรือ LEA ใช้ใน x86 ไม่รองรับตัวคูณสเกล 3 รองรับเฉพาะกำลังของ 2 อย่าง 1, 2, 4, 8 เท่านั้น ดังนั้นในการสร้างที่อยู่จึงไม่มีที่ให้ใช้การคูณด้วย 3 เท่า
บทความระบุไว้อย่างชัดเจนว่าตัวคูณ 3 เท่าเป็นส่วนหนึ่งของตัวคูณแบบจุดลอยตัว
“ตัวคูณ ×3 นี้มีทรานซิสเตอร์ประมาณ 9000 ตัว ซึ่งมากกว่าทั้งไมโครโปรเซสเซอร์ Z80 (1976) อยู่เล็กน้อย จงจำไว้ว่าตัวคูณ ×3 เป็นเพียงส่วนเล็ก ๆ ของตัวคูณแบบจุดลอยตัวภายในหน่วยจุดลอยตัวของ Pentium กล่าวคือ ชิ้นส่วนเล็ก ๆ ของฟังก์ชันหนึ่งมีความซับซ้อนมากกว่าไมโครโปรเซสเซอร์ทั้งตัวเมื่อ 17 ปีก่อน และนี่แสดงให้เห็นว่าความซับซ้อนของโปรเซสเซอร์เพิ่มขึ้นอย่างมหาศาลเพียงใด”
อัตราการเติบโตของประสิทธิภาพ แบบนี้เองที่ก่อให้เกิดซอฟต์แวร์บวมในปัจจุบัน เพราะการเพิ่มขึ้นของประสิทธิภาพในปีถัดไปมักกลบความผิดจากการไม่คิดอย่างวิพากษ์เกี่ยวกับอัลกอริทึม บริบทของการไหลของข้อมูล และ locality ได้เกือบหมด
ทุกวันนี้เท่าที่ผมอ่านมา เราไปถึงขีดจำกัดเชิงปฏิบัติของสิ่งที่ทำได้อย่างสมเหตุสมผลด้วยเทคโนโลยีสารกึ่งตัวนำซิลิคอนและความเข้าใจทางฟิสิกส์ในปัจจุบันแล้ว ตอนนี้ลูกตุ้มควรต้องแกว่งกลับอีกทาง คอมพิวเตอร์ต้องทำงาน ฉลาดขึ้น ไม่ใช่หนักขึ้น
แต่ผมมองว่าซอฟต์แวร์บวมกำลังโตเร็วกว่า
goto/jmp→ ค้นหา vtable → แฮชและค้นหาในดิกชันนารี → รัน โมเดลภาษาขนาดใหญ่“แทนที่จะคูณด้วย 7 ก็เอาจำนวนคูณ 8 แล้วลบจำนวนนั้นออกเพื่อให้ได้ 7 เท่า อาจดูเหมือนต้องใช้สองขั้นตอน แต่ด้วยเทคนิคการคูณเพิ่มอีก 1 ที่หลักทางซ้าย จึงได้สัมประสิทธิ์ 8 เท่าโดยไม่ต้องมีขั้นตอนเพิ่มเติม”
นี่หมายความว่าก่อนใส่ตัวเลขเข้าไปในส่วนตัวคูณหลัก มี ตัวบวก ที่เพิ่ม 1 ให้กับ “หลักถัดไป” ใช่ไหม? ตัวมันเองก็ดูคล้ายกับวงจรทำนายตัวทดด้วย
ยังทำให้คิดด้วยว่าเมื่อไรถึงจำเป็นต้องใช้สิ่งนี้:
7 = 8-1,6 = 8-2,5 = 8-3,4 = 8-4กรณีสุดท้ายบทความไม่ได้บอกว่าทำแบบนั้น แต่ถ้าใช้บิตที่มีนัยสำคัญสูงสุดของค่า 3 บิตเพื่อตัดสินว่าต้องเพิ่ม 1 ให้หลักถัดไปหรือไม่ ก็น่าจะประหยัดเกตได้ไม่กี่ตัว
น่าสนใจที่เลือก ตัวคูณ Booth ฐาน 8 ซึ่งต้องใช้วงจร ×3 ดูเหมือนเป็นการแลกพื้นที่/ประสิทธิภาพเพื่อดันความถี่สูงสุดให้สูงขึ้น และเรื่องเดียวกันก็น่าจะทำได้ด้วยการทำไพป์ไลน์เพิ่ม จึงดูเหมือนว่ามีข้อจำกัดเรื่องไซเคิลหน่วงเวลา
การทำไพป์ไลน์ยุ่งยาก เพราะไม่มีตำแหน่งที่ดีสำหรับแบ่งอาร์เรย์คูณออกเป็นสองส่วน
https://github.com/EI2030/Low-power-E-Paper-OS/blob/master/P...
8086: 29,000
386: 275,000
486: 1.2 ล้าน
Pentium: 3.1 ล้าน
เท่าที่ผมจำได้ NSA เข้ามาอยู่ในเกมนี้หลังปี 2000 ณ ช่วงเวลาใดเวลาหนึ่ง