ทำไมคุณถึงตั้งโปรแกรมในการประกอบ? [ปิด]


86

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

ตัวอย่างเช่นเกม 3 มิติสมัยใหม่จำนวนมากมีเอ็นจิ้นหลักประสิทธิภาพสูงที่เขียนด้วย C ++ และ Assembly

เท่าที่แอสเซมบลีจะดำเนินไป - คือโค้ดที่เขียนขึ้นในแอสเซมบลีเนื่องจากคุณไม่ต้องการให้คอมไพเลอร์ปล่อยคำสั่งพิเศษหรือใช้ไบต์มากเกินไปหรือคุณใช้อัลกอริทึมที่ดีกว่าซึ่งคุณไม่สามารถแสดงใน C (หรือไม่สามารถแสดงออกได้โดยไม่ต้อง คอมไพเลอร์รวบรวมพวกเขาขึ้น)?

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


1
มีคำถามคล้าย ๆ กันอยู่แล้วฉันคิดว่า ...
mmx

8
Eeeeehh .. ในทางเทคนิคนี่เป็นคำถามที่แตกต่างกัน คำถามเหล่านั้นคือทำไมต้องเรียนรู้แอสเซมบลีนี่คือทำไมโปรแกรมในนั้นซึ่ง .. ฉันคิดว่าแตกต่างกัน ....
cgp

4
ทำไมคุณถึงตั้งโปรแกรมในการประกอบ? - ลองดูคำตอบที่เป็นไปไม่ได้สำหรับคำถามนั้น: 1) เพื่อให้รหัสของฉันสามารถบำรุงรักษาได้ 2) มีความยืดหยุ่น 3) เพื่อให้สามารถพกพาได้ 4) ทดสอบได้ 5) ความสามารถในการอ่าน ... ;)
ivan_ivanovich_ivanoff

9
job security ........
San Jacinto

3
เพราะมันสนุก .. :)
RainingComputers

คำตอบ:


170

ฉันคิดว่าคุณกำลังอ่านข้อความนี้ผิด:

ตัวอย่างเช่นเกม 3 มิติสมัยใหม่จำนวนมากมีเอ็นจิ้นหลักประสิทธิภาพสูงที่เขียนด้วย C ++ และ Assembly

เกม (และโปรแกรมส่วนใหญ่ในปัจจุบัน) ไม่ได้ "เขียนแบบประกอบ" แบบเดียวกับที่ "เขียนด้วยภาษา C ++" บล็อกนั้นไม่ได้บอกว่าส่วนสำคัญของเกมได้รับการออกแบบในการประกอบหรือทีมโปรแกรมเมอร์นั่งอยู่รอบ ๆ และพัฒนาแอสเซมบลีเป็นภาษาหลัก

สิ่งนี้หมายความว่าจริงๆแล้วนักพัฒนาจะเขียนเกมก่อนและทำให้มันทำงานใน C ++ จากนั้นพวกเขาก็กำหนดรายละเอียดหาว่าคอขวดคืออะไรและถ้ามันคุ้มค่าพวกเขาก็เพิ่มประสิทธิภาพของมันในการประกอบ หรือถ้าพวกเขามีประสบการณ์อยู่แล้วพวกเขาจะรู้ว่าส่วนใดที่จะเป็นคอขวดและพวกเขาก็มีชิ้นส่วนที่เหมาะสมจากเกมอื่น ๆ ที่พวกเขาสร้างขึ้น

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

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

นี่คือตัวอย่างที่เกี่ยวข้องเพิ่มเติม:

ตัวอย่างจากเกม

  • บทความจาก Intelเกี่ยวกับการปรับแต่งเกมเอนจิ้นโดยใช้ SSE intrinsics โค้ดสุดท้ายใช้อินทรินซิค (ไม่ใช่อินไลน์แอสเซมเบลอร์) ดังนั้นจำนวนแอสเซมบลีที่บริสุทธิ์จึงมีน้อยมาก แต่พวกเขามองไปที่เอาต์พุตของแอสเซมเบลอร์โดยคอมไพเลอร์เพื่อหาว่าจะปรับให้เหมาะสมอย่างไร

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

คอมพิวเตอร์ประสิทธิภาพสูง

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

    ตัวอย่างล่าสุดที่ดีของที่นี่คือLattice ควอนตัม chromodynamics (Lattice QCD) บทความนี้อธิบายวิธีปัญหาสวยมากเดือดลงไปหนึ่งเคอร์เนลคอมพิวเตอร์ขนาดเล็กมากซึ่งได้รับการปรับให้เหมาะสมอย่างยิ่งสำหรับ PowerPC 440 ของบนIBM ยีนสีน้ำเงิน / L 440 แต่ละคนมี FPU สองตัวและสนับสนุนการดำเนินการด้านท้ายพิเศษบางอย่างที่ยากสำหรับคอมไพเลอร์ในการใช้ประโยชน์ หากไม่มีการเพิ่มประสิทธิภาพเหล่านี้ Lattice QCD จะทำงานช้าลงมากซึ่งมีค่าใช้จ่ายสูงเมื่อปัญหาของคุณต้องใช้ CPU หลายล้านชั่วโมงในเครื่องราคาแพง

    หากคุณสงสัยว่าเหตุใดจึงสำคัญโปรดอ่านบทความใน Scienceที่มาจากงานนี้ การใช้ Lattice QCD พวกนี้คำนวณมวลของโปรตอนจากหลักการแรกและแสดงให้เห็นเมื่อปีที่แล้วว่า 90% ของมวลมาจากพลังงานยึดเหนี่ยวแรงและส่วนที่เหลือมาจากควาร์ก นั่นคือE = mc 2ในการดำเนินการ นี่สรุป

สำหรับทั้งหมดข้างต้นแอปพลิเคชันไม่ได้รับการออกแบบหรือเขียนขึ้น 100% ในการประกอบ - ไม่แม้แต่จะปิด แต่เมื่อผู้คนต้องการความเร็วจริงๆพวกเขามุ่งเน้นไปที่การเขียนส่วนสำคัญของโค้ดเพื่อบินบนฮาร์ดแวร์เฉพาะ


12
การตอบสนองที่น่าทึ่ง หวังว่าเราจะใส่สิ่งนี้ไว้ใน wiki!
bdd

6
@Paperino ... ทำได้. คำถามและคำตอบใน StackOverflow คือการระบุแหล่งที่มาของครีเอทีฟคอมมอนส์ที่ได้รับอนุญาต
Aaron Maenpaa

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการทำความเข้าใจ asm เพื่อช่วยให้คุณเขียน C / C ++ ได้ดีขึ้นโปรดดูเหตุใดโค้ด C ++ นี้จึงเร็วกว่าแอสเซมบลีที่เขียนด้วยมือของฉันสำหรับการทดสอบการคาดเดา Collatz . คำตอบของฉันชี้ให้เห็นว่าการอ่านเอาต์พุต asm ของคอมไพเลอร์และการปรับแต่งซอร์สสามารถช่วยได้เมื่อคอมไพเลอร์ไม่สังเกตเห็นการเพิ่มประสิทธิภาพที่เป็นประโยชน์ ดังนั้นคุณจึงเขียนด้วยความคิด (หรือจริงๆ) ใน asm จากนั้นจับคอมไพเลอร์ด้วยมือเพื่อทำสิ่งที่คุณต้องการ แต่ตอนนี้คุณมี C. แบบพกพาที่พิสูจน์ได้ในอนาคต
Peter Cordes

42

ฉันไม่ได้เขียนโค้ดด้วยภาษาแอสเซมบลีมาหลายปีแล้ว แต่ฉันสามารถให้เหตุผลหลายประการที่ฉันเห็นบ่อยๆ:

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

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

  • การเข้าถึงระดับฮาร์ดแวร์บางอย่างสามารถทำได้ / ใช้งานได้จริงผ่านภาษาแอสเซมบลีเท่านั้น (เช่นเมื่อเขียนไดรเวอร์อุปกรณ์)

  • การให้เหตุผลอย่างเป็นทางการในบางครั้งภาษาแอสเซมบลีนั้นง่ายกว่าภาษาระดับสูงเนื่องจากคุณรู้แล้วว่าเลย์เอาต์สุดท้ายหรือเกือบสุดท้ายของโค้ดคืออะไร

  • การเขียนโปรแกรมกราฟิกการ์ด 3 มิติ (ประมาณปลายทศวรรษ 1990) ในกรณีที่ไม่มี API มักใช้ภาษาแอสเซมบลีและมีประสิทธิภาพมากกว่าและบางครั้งก็ใช้ไม่ได้ในภาษาอื่น แต่อีกครั้งสิ่งนี้เกี่ยวข้องกับเกมระดับผู้เชี่ยวชาญจริงๆโดยใช้สถาปัตยกรรมตัวเร่งความเร็วเช่นการย้ายข้อมูลเข้าและออกด้วยตนเองตามลำดับที่กำหนด

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


19

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


3
เฮ้มันเป็นผลมาจากการทำงานของแอสเซมเบลอร์! คุณมักจะเขียนมาโครจำนวนมากใน asm
mmx

5
ไม่ใช่แค่ความพึงพอใจ แต่เป็นการชื่นชมความแม่นยำ กระบวนการที่รัดกุมพร้อมทุกสิ่งที่ประกาศเป็นความสุขที่ได้เห็น
deau

18

โดยปกติแล้วแอสเซมบลีของคนธรรมดาจะช้ากว่า C (เนื่องจากการเพิ่มประสิทธิภาพของ C) แต่หลาย ๆ เกม (ฉันจำDoomได้อย่างชัดเจน) ต้องมีส่วนเฉพาะของเกมในแอสเซมบลีดังนั้นจึงจะทำงานได้อย่างราบรื่นบนเครื่องปกติ

นี่คือตัวอย่างที่ฉันอ้างถึง


2
+1 จริงมาก มนุษย์แย่มากในการเขียนโค้ด asm ยาว ๆ
บัญชีตาย

โปรดทราบว่าเครื่องมือดังกล่าวไม่สามารถใช้ได้ตลอดเวลาเมื่อเขียนแอสเซมเบลอร์
Marco van de Voort

16

ฉันเริ่มเขียนโปรแกรมมืออาชีพในภาษาแอสเซมบลีในงานแรกของฉัน (ยุค 80) สำหรับระบบฝังตัวความต้องการหน่วยความจำ - RAM และ EPROM มีน้อย คุณสามารถเขียนโค้ดที่แน่นซึ่งง่ายต่อทรัพยากร

ในช่วงปลายยุค 80 ฉันได้เปลี่ยนมาใช้ C รหัสนั้นเขียนแก้ไขข้อบกพร่องและดูแลรักษาได้ง่ายขึ้น มีการเขียนโค้ดขนาดเล็กมากในแอสเซมเบลอร์ - สำหรับฉันแล้วตอนที่ฉันกำลังเขียนการสลับบริบทใน RTOS ของคุณเอง (สิ่งที่คุณไม่ควรทำอีกต่อไปเว้นแต่จะเป็น "โครงงานวิทยาศาสตร์")

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

ฉันคิดว่าคุณคงยากที่จะปรับแต่งคอมไพเลอร์ C สมัยใหม่สำหรับการเขียนโปรแกรมทั่วไปส่วนใหญ่

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

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


10

"ใช่". แต่เข้าใจว่าส่วนใหญ่แล้วประโยชน์ของการเขียนโค้ดในแอสเซมเบลอร์นั้นไม่คุ้มค่ากับความพยายาม ผลตอบแทนที่ได้รับจากการเขียนในแอสเซมบลีมีแนวโน้มที่จะน้อยกว่าการมุ่งเน้นไปที่การคิดให้หนักขึ้นเกี่ยวกับปัญหาและใช้เวลาของคุณในการคิดหาวิธีที่ดีกว่าในการทำ thigns

John Carmack และ Michael Abrash ซึ่งเป็นผู้รับผิดชอบส่วนใหญ่ในการเขียน Quake และโค้ดประสิทธิภาพสูงทั้งหมดที่เข้าสู่เอ็นจิ้นการเล่นเกมของ ID จะกล่าวถึงรายละเอียดโดยละเอียดในหนังสือเล่มนี้

ฉันยังเห็นด้วยกับÓlafur Waage ที่ทุกวันนี้คอมไพเลอร์ค่อนข้างฉลาดและมักใช้เทคนิคมากมายที่ใช้ประโยชน์จากการเพิ่มสถาปัตยกรรมที่ซ่อนอยู่


9

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


ในกรณีนั้นฉันจะใช้คอมไพเลอร์ที่อยู่ภายใน
mmx

ยังคงไม่เหมือนเดิม. มันเหมือนกับคอมไพเลอร์ที่ไม่มีตัวเพิ่มประสิทธิภาพการลงทะเบียน
Marco van de Voort

ขึ้นอยู่กับว่าโปรแกรมเมอร์ asm ของคุณปรุงรสแบบไหน ถ้าคุณได้อ่านและ grokked agner.org/optimizeเรียนรู้เกี่ยวกับสถาปัตยกรรมที่คุณจูนกำลังสำหรับเต้นคอมไพเลอร์สำหรับลำดับสั้น ๆ เท่านั้น มักจะเป็นเรื่องง่าย อย่างน้อยครึ่งหนึ่งของเวลาที่ฉันพลาดการปรับแต่งเล็กน้อยเมื่อมองไปที่เอาต์พุตคอมไพเลอร์สำหรับฟังก์ชันขนาดเล็ก ในกรณีที่คอมไพเลอร์ยอดเยี่ยมคือการปรับให้เหมาะสมกับโค้ดเบสขนาดใหญ่ที่มีอินไลน์และการขยายพันธุ์คงที่
Peter Cordes

8

รหัส SSE ทำงานได้ดีกว่าในแอสเซมบลีมากกว่า Intrinsics ของคอมไพเลอร์อย่างน้อยก็ใน MSVC (เช่นไม่สร้างสำเนาข้อมูลเพิ่มเติม)


จุดดีคุณต้องมีคอมไพเลอร์ที่ทำงานได้ดีกับเนื้อแท้ คอมไพเลอร์ Intel และ Gnu ค่อนข้างดีฉันไม่รู้ว่าล่าสุดจาก PGI และ PathScale สามารถแข่งขันได้หรือไม่พวกเขาไม่เคยเป็นมาก่อน
Jed

6

ฉันมีรูทีนแอสเซมเบลอร์สามหรือสี่รายการ (ในซอร์สประมาณ 20 MB) ในแหล่งที่มาในที่ทำงาน ทั้งหมดนี้เป็นSSE (2)และเกี่ยวข้องกับการดำเนินการบน (ค่อนข้างใหญ่ - คิดว่า 2400x2048 ขึ้นไป)

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

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

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

หลายคนคิดว่าการฝังตัวเป็นข้ออ้างสำหรับแอสเซมเบลอร์ แต่คอนโทรลเลอร์ของพวกเขามีพลังงาน CPU มากกว่าเครื่องที่Unixได้รับการพัฒนา (ไมโครชิพมาพร้อมกับไมโครคอนโทรลเลอร์ 40 และ 60 MIPSสำหรับภายใต้ 10 เหรียญสหรัฐ )

อย่างไรก็ตามผู้คนจำนวนมากติดอยู่กับมรดกตกทอดเนื่องจากการเปลี่ยนสถาปัตยกรรมไมโครชิปไม่ใช่เรื่องง่าย นอกจากนี้โค้ด HLL ยังขึ้นอยู่กับสถาปัตยกรรมเป็นอย่างมาก (เนื่องจากใช้อุปกรณ์ต่อพ่วงฮาร์ดแวร์รีจิสเตอร์เพื่อควบคุม I / O ฯลฯ ) ดังนั้นจึงมีเหตุผลที่ดีในการดูแลโครงการในแอสเซมเบลอร์ต่อไป (ฉันโชคดีที่สามารถตั้งค่ากิจการบนสถาปัตยกรรมใหม่ตั้งแต่เริ่มต้น) แต่บ่อยครั้งที่ผู้คนมักคิดว่าพวกเขาต้องการผู้ประกอบ

ฉันยังคงชอบคำตอบที่ศาสตราจารย์ให้ไว้เมื่อเราถามว่าเราสามารถใช้ GOTO ได้หรือไม่ (แต่คุณสามารถอ่านเป็น ASSEMBLER ได้เช่นกัน): "ถ้าคุณคิดว่ามันคุ้มค่าที่จะเขียนเรียงความ 3 หน้าว่าทำไมคุณถึงต้องการฟีเจอร์นี้คุณสามารถใช้ได้ . กรุณาส่งเรียงความพร้อมผลลัพธ์ของคุณ "

ฉันใช้สิ่งนั้นเป็นแนวทางสำหรับคุณสมบัติระดับต่ำ อย่าคับแคบเกินไปที่จะใช้มัน แต่ให้แน่ใจว่าคุณกระตุ้นมันอย่างเหมาะสม แม้กระทั่งโยนสิ่งกีดขวางเทียมหรือสองอัน (เช่นเรียงความ) เพื่อหลีกเลี่ยงการใช้เหตุผลที่ซับซ้อนเป็นเหตุผล


1
ฉันชอบแบบทดสอบเรียงความ ฉันอาจต้องใช้สิ่งนี้บ่อยขึ้น;)
โฆษณาไร้สาระ

5

คำแนะนำ / แฟล็ก / การควบคุมบางอย่างไม่ได้อยู่ที่ระดับ C

ตัวอย่างเช่นการตรวจสอบ overflow บน x86 คือแฟล็ก overflow ธรรมดา ตัวเลือกนี้ไม่มีใน C


คุณสามารถคำนวณแฟล็กล้นใน C ด้วยการดำเนินการบิต
swegi

@swegi: ฉันพนันได้เลยว่ามันช้าลงอย่างไม่มีนัยสำคัญ
Brian

บ่อยแค่ไหนที่มีประโยชน์? และเมื่อเป็นเช่นนั้นก็ไม่อาจเป็นเหตุผลเดียวที่จะทิ้งลงในแอสเซมเบลอร์

5

ข้อบกพร่องมักจะทำงานต่อบรรทัด (คำสั่งจุดรหัส ฯลฯ ); ในขณะที่เป็นความจริงสำหรับปัญหาส่วนใหญ่แอสเซมบลีจะใช้บรรทัดมากกว่าภาษาระดับสูงกว่า แต่ก็มีบางครั้งที่การแมปที่ดีที่สุด (กระชับที่สุดและน้อยที่สุด) จะแมปกับปัญหาในมือ กรณีเหล่านี้ส่วนใหญ่เกี่ยวข้องกับผู้ต้องสงสัยตามปกติเช่นไดรเวอร์และการกัดบิตในระบบฝังตัว


3

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


3

นอกเหนือจากสิ่งอื่น ๆ ที่กล่าวถึงแล้วภาษาที่สูงขึ้นทั้งหมดมีข้อ จำกัด บางประการ นั่นเป็นเหตุผลที่บางคนเลือกที่จะเขียนโปรแกรมใน ASM เพื่อให้สามารถควบคุมโค้ดของตนได้อย่างเต็มที่

คนอื่น ๆ ชอบโปรแกรมปฏิบัติการขนาดเล็กมากในช่วง 20-60KB เช่นตรวจสอบHiEditorซึ่งดำเนินการโดยผู้เขียนการควบคุม HiEdit การควบคุมการแก้ไขที่มีประสิทธิภาพที่ยอดเยี่ยมสำหรับ Windows พร้อมการเน้นไวยากรณ์และแท็บในเพียง ~ 50kb) ในคอลเลกชันของฉันฉันมีการควบคุมทองคำมากกว่า 20 รายการจาก Excell เช่น ssheets ไปจนถึง html


3

ฉันคิดว่าผู้พัฒนาเกมหลายคนคงจะประหลาดใจกับข้อมูลเล็กน้อยนี้

เกมส่วนใหญ่ที่ฉันรู้จักใช้ประกอบน้อยที่สุดเท่าที่จะทำได้ ในบางกรณีไม่มีเลยและที่แย่ที่สุดคือหนึ่งหรือสองลูปหรือฟังก์ชัน

คำพูดนั้นเป็นคำพูดที่กว้างเกินไปและไม่มีที่ไหนใกล้เคียงความจริงเหมือนเมื่อทศวรรษที่แล้ว

แต่เดี๋ยวก่อนข้อเท็จจริงไม่ควรขัดขวางสงครามครูเสดที่แท้จริงของแฮ็กเกอร์เพื่อสนับสนุนการชุมนุม ;)


3

หากคุณกำลังเขียนโปรแกรมไมโครคอนโทรลเลอร์ 8 บิตระดับล่างที่มี RAM 128 ไบต์และหน่วยความจำโปรแกรม 4K คุณไม่มีทางเลือกมากนักในการใช้แอสเซมบลี ในบางครั้งแม้ว่าเมื่อใช้ไมโครคอนโทรลเลอร์ที่ทรงพลังกว่าคุณก็ต้องดำเนินการบางอย่างในเวลาที่แน่นอน ภาษาแอสเซมบลีมีประโยชน์ในขณะที่คุณสามารถนับคำแนะนำและวัดรอบนาฬิกาที่ใช้โดยรหัสของคุณ


2

หากคุณอยู่ใกล้กับความพยายามในการแก้ไข Y2K ทั้งหมดคุณสามารถทำเงินได้มากมายหากคุณรู้จัก Assembly ยังมีรหัสเดิมอีกมากมายที่เขียนอยู่ในนั้นและบางครั้งรหัสนั้นก็ต้องได้รับการบำรุงรักษา


2

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

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

ตัวอย่างเช่น SH4 บางรุ่นมีเมทริกซ์ 4x4 และเวกเตอร์ 4 คำสั่ง ฉันเห็นการปรับปรุงประสิทธิภาพอย่างมากในอัลกอริธึมการแก้ไขสีโดยแทนที่การดำเนินการ C ที่เท่ากันบนเมทริกซ์ 3x3 ด้วยคำแนะนำที่เหมาะสมโดยเสียค่าใช้จ่ายเพียงเล็กน้อยในการขยายเมทริกซ์การแก้ไขเป็น 4x4 เพื่อให้ตรงกับสมมติฐานของฮาร์ดแวร์ ซึ่งทำได้โดยการเขียนชุดประกอบไม่เกินโหลและดำเนินการปรับเปลี่ยนการจับคู่ประเภทข้อมูลที่เกี่ยวข้องและการจัดเก็บในสถานที่ไม่กี่แห่งในรหัส C โดยรอบ


2

ดูเหมือนจะไม่ได้กล่าวถึงดังนั้นฉันคิดว่าฉันจะเพิ่มเข้าไป: ในการพัฒนาเกมสมัยใหม่ฉันคิดว่าอย่างน้อยแอสเซมบลีบางส่วนที่เขียนขึ้นนั้นไม่ได้มีไว้สำหรับ CPU เลย สำหรับ GPU ในรูปแบบของโปรแกรม shaderโปรแกรม

สิ่งนี้อาจจำเป็นสำหรับเหตุผลหลายประการบางครั้งอาจเป็นเพราะภาษาแรเงาระดับสูงที่ใช้ไม่อนุญาตให้แสดงการดำเนินการที่แน่นอนตามจำนวนคำสั่งที่ต้องการเพื่อให้พอดีกับข้อ จำกัด ขนาดความเร็วหรือการผสมผสานใด ๆ . ฉันเดาว่าเช่นเดียวกับการเขียนโปรแกรมภาษาแอสเซมบลี


2

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

ฉันยังเห็นว่าแอสเซมบลีรหัสด้วยมือใช้บ่อยมากสำหรับการจัดส่งแบบกำหนดเองเช่น FastDelegate แต่คอมไพเลอร์และเครื่องเฉพาะ

สุดท้ายหากคุณมี Interrupt Service Routines asm สามารถสร้างความแตกต่างในโลกได้ - มีการดำเนินการบางอย่างที่คุณไม่ต้องการให้เกิดขึ้นภายใต้การขัดจังหวะและคุณต้องการให้ตัวจัดการการขัดจังหวะของคุณ "เข้าและออกอย่างรวดเร็ว" .. คุณรู้เกือบหมดแล้วว่าจะเกิดอะไรขึ้นใน ISR ของคุณถ้ามันอยู่ใน asm และมันกระตุ้นให้คุณเก็บสิ่งที่เปื้อนเลือดไว้ให้สั้น (ซึ่งก็เป็นแนวทางปฏิบัติที่ดีอยู่ดี)


2

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

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


2

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

  1. ความเร็ว: ความล่าช้าต้องน้อยที่สุด
  2. ค่าใช้จ่าย: ด้วยการใช้โค้ดเพียงเล็กน้อยฮาร์ดแวร์ที่จำเป็นในการเรียกใช้อาจมีประสิทธิภาพน้อยกว่าเล็กน้อย เมื่อผลิตจำนวนมากได้หลายล้านหน่วยสิ่งนี้สามารถเพิ่มได้

2

การเข้ารหัสแอสเซมเบลอร์เดียวที่ฉันทำต่อไปคือสำหรับฮาร์ดแวร์แบบฝังที่มีทรัพยากรไม่เพียงพอ ดังที่กล่าวถึงการใช้พลังงานอย่างมีประสิทธิภาพการประกอบยังคงเหมาะกับISRที่รหัสต้องรวดเร็วและเข้าใจได้ดี

เหตุผลรองสำหรับฉันคือการรักษาความรู้เกี่ยวกับการประกอบใช้งานได้ ความสามารถในการตรวจสอบและทำความเข้าใจขั้นตอนที่ CPU ใช้ในการเสนอราคาของฉันก็รู้สึกดี


2

ครั้งสุดท้ายที่ฉันเขียนในแอสเซมเบลอร์คือตอนที่ฉันไม่สามารถโน้มน้าวให้คอมไพเลอร์สร้างโค้ดอิสระที่ไม่มีตำแหน่ง libc ได้

ครั้งต่อไปก็คงด้วยเหตุผลเดียวกัน

แน่นอนผมเคยมีอื่น ๆเหตุผล


2

ผู้คนจำนวนมากชอบที่จะลบล้างภาษาแอสเซมบลีเพราะพวกเขาไม่เคยเรียนรู้ที่จะเขียนโค้ดด้วยซ้ำและพบเจอ แต่ความคลุมเครือเท่านั้นและมันทำให้พวกเขาตกใจหรือค่อนข้างกลัว โปรแกรมเมอร์ที่มีความสามารถอย่างแท้จริงจะเข้าใจว่าการทุบตี C หรือ Assembly นั้นเป็นเรื่องที่ไม่สมควรเพราะเป็นอภินันทนาการ ในความเป็นจริงข้อดีของข้อหนึ่งคือข้อเสียของอีกฝ่าย กฎไวยากรณ์ที่มีการจัดระเบียบของ C ช่วยเพิ่มความชัดเจน แต่ในขณะเดียวกันก็ให้การประกอบกำลังทั้งหมดที่มีจากการปราศจากกฎเกณฑ์โครงสร้างใด ๆ ! คำสั่งรหัส C ถูกสร้างขึ้นเพื่อสร้างรหัสที่ไม่ปิดกั้นซึ่งอาจมีการโต้แย้งบังคับให้มีความชัดเจนของเจตนาในการเขียนโปรแกรม แต่นี่เป็นการสูญเสียพลังงาน ใน C คอมไพลเลอร์จะไม่อนุญาตให้กระโดดภายใน if / elseif / else / end หรือคุณไม่ได้รับอนุญาตให้เขียนสองสำหรับ / สิ้นสุดลูปบนตัวแปรต่าง ๆ ที่ทับซ้อนกัน คุณไม่สามารถเขียนโค้ดดัดแปลงตัวเองได้ (หรือไม่สามารถทำได้ด้วยวิธีง่ายๆอย่างราบรื่น) ฯลฯ โปรแกรมเมอร์ทั่วไปถูกหลอกโดยข้างต้นและไม่มีความคิดที่จะใช้พลังของวิธีการเหล่านี้ด้วยซ้ำเนื่องจากพวกเขาได้รับการยกให้เป็นไปตามกฎทั่วไป . นี่คือความจริง: วันนี้เรามีเครื่องจักรที่มีพลังในการประมวลผลเพื่อทำอะไรได้มากขึ้นกว่าที่แอปพลิเคชันที่เราใช้ แต่สมองของมนุษย์ไม่สามารถเขียนโค้ดได้ในสภาพแวดล้อมการเข้ารหัสที่ปราศจากกฎ (= แอสเซมบลี) และต้องการกฎเกณฑ์ที่ จำกัด อย่างมาก ลดสเปกตรัมและลดความยุ่งยากในการเข้ารหัส ฉันเขียนโค้ดด้วยตัวเองซึ่งไม่สามารถเขียนด้วยรหัส C ได้โดยที่ไม่มีประสิทธิภาพอย่างมากเนื่องจากข้อ จำกัด ที่กล่าวถึงข้างต้น และฉันยังไม่ได้พูดถึงความเร็วซึ่งคนส่วนใหญ่คิดว่าเป็นสาเหตุหลักในการเขียนประกอบ ถ้าคุณคิดว่าจะ จำกัด เฉพาะการคิดใน C คุณก็จะเป็นทาสของคอมไพเลอร์ตลอดไป ฉันคิดเสมอว่าผู้เชี่ยวชาญด้านการเล่นหมากรุกจะเป็นนักเขียนโปรแกรมประกอบในอุดมคติในขณะที่โปรแกรมเมอร์ C เล่น "Dames"


1
โค้ดที่ปรับเปลี่ยนได้เองไม่มีประโยชน์สำหรับประสิทธิภาพของ CPU ที่ทันสมัยส่วนใหญ่นอกสถานการณ์ JIT-once / run-many แต่การเติมค่าคงที่ในทันทีนั้นเป็นไปได้ที่น่าสนุก C gotoอนุญาตให้กระโดดแบบไม่มีโครงสร้างภายในฟังก์ชันได้ รวมเข้าไปในบล็อกภายในif()หรือวนซ้ำในฟังก์ชันเดียวกัน เช่นgodbolt.org/z/IINHTg ดูอุปกรณ์ของ Duff ด้วยโดยใช้สวิตช์ / เคสเป็นdo{}while()ลูปเพื่อแสดงการกระโดดเข้าสู่ลูปที่ไม่มีการควบคุม แต่ในบางจุดการเขียน asm จะชัดเจนขึ้นถ้าคุณลงไปถึงระดับความยุ่งเหยิง
Peter Cordes

1
(แน่นอนว่าอุปกรณ์ของดัฟฟ์มีประโยชน์เฉพาะกับเครื่องที่มีการกำหนดแอดเดรสโพสต์เพิ่มเท่านั้นมิฉะนั้นจุดเข้าที่อยู่ในลูปที่ไม่มีการควบคุมจะเอาชนะจุดประสงค์ส่วนใหญ่ของการเพิ่มประสิทธิภาพ)
Peter Cordes

1

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


1

ถ้าฉันสามารถทำได้ดีกว่าGCCและ Visual C ++ 2008 (เรียกอีกอย่างว่า Visual C ++ 9.0) ผู้คนจะสนใจสัมภาษณ์ฉันเกี่ยวกับความเป็นไปได้

นี่คือเหตุผลว่าทำไมตอนนี้ฉันเพิ่งอ่านสิ่งต่างๆในการประกอบและเขียน __asm ​​int 3 เมื่อจำเป็น

ฉันหวังว่านี่จะช่วยได้ ...


1

ฉันไม่ได้เขียนในการชุมนุมมาสองสามปีแล้ว แต่เหตุผลสองประการที่ฉันเคยทำคือ:

  • ความท้าทายของสิ่ง! ฉันผ่านช่วงเวลาหลายเดือนเมื่อหลายปีก่อนเมื่อฉันเขียนทุกอย่างในแอสเซมบลี x86 (สมัยของDOSและ Windows 3.1) โดยพื้นฐานแล้วมันสอนให้ฉันรู้ถึงการใช้งานระดับต่ำฮาร์ดแวร์I / Oฯลฯ
  • สำหรับบางสิ่งก็มีขนาดเล็ก (อีกครั้ง DOS และWindows 3.1เมื่อเขียนTSR s)

ฉันมองไปที่ชุดประกอบการเข้ารหัสอีกครั้งและไม่มีอะไรมากไปกว่าความท้าทายและความสุขของสิ่งนั้น ฉันไม่มีเหตุผลอื่นที่จะทำ :-)


1

ฉันเคยเข้ารับช่วงโครงการ DSP ซึ่งโปรแกรมเมอร์คนก่อนหน้าส่วนใหญ่เขียนด้วยรหัสแอสเซมบลียกเว้นตรรกะการตรวจจับโทนเสียงที่เขียนด้วยภาษา C โดยใช้ทศนิยม (บน DSP จุดคงที่!) ตรรกะการตรวจจับโทนทำงานที่ประมาณ 1/20 ของเวลาจริง

ฉันเขียนใหม่เกือบทุกอย่างตั้งแต่เริ่มต้น เกือบทุกอย่างอยู่ใน C ยกเว้นตัวจัดการขัดจังหวะขนาดเล็กและโค้ดสองสามบรรทัดที่เกี่ยวข้องกับการจัดการขัดจังหวะและการตรวจจับความถี่ระดับต่ำซึ่งทำงานได้เร็วกว่ารหัสเดิมถึง 100 เท่า

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


0

Dalvik VM ที่ตีความ bytecode สำหรับแอปพลิเคชัน Java บนโทรศัพท์ Android ใช้แอสเซมเบลอร์สำหรับดิสแพตเชอร์ ภาพยนตร์เรื่องนี้(ประมาณ 31 นาที แต่คุ้มค่ากับการชมภาพยนตร์ทั้งเรื่อง!) อธิบายวิธีการ

"ยังมีบางกรณีที่มนุษย์สามารถทำได้ดีกว่าคอมไพเลอร์"


0

ฉันไม่ได้ แต่ฉันได้พยายามอย่างน้อยที่สุดและพยายามอย่างเต็มที่ในบางช่วงเวลา (หวังว่าในไม่ช้า) การทำความรู้จักกับสิ่งที่มีระดับต่ำมากขึ้นไม่ใช่เรื่องเลวร้ายและวิธีการทำงานเบื้องหลังเมื่อฉันเขียนโปรแกรมด้วยภาษาระดับสูง น่าเสียดายที่เวลามาด้วยงานประจำในฐานะนักพัฒนา / ที่ปรึกษาและผู้ปกครองนั้นยาก แต่ฉันจะให้ไปตามเวลาที่กำหนดแน่นอน

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