กลับไปหน้าบทความ

อ่าน 6 นาที

การกำจัดโค้ดที่ไม่ได้ใช้งาน

ใน ทฤษฎีคอมไพเลอร์ การ กำจัดโค้ดที่ไม่ใช้งาน ( DCE , การลบโค้ดที่ไม่ใช้งาน , การตัดโค้ดที่ไม่ใช้งาน หรือ การตัดโค้ดที่ไม่ใช้งาน ) เป็นการ เพิ่มประสิทธิภาพของคอมไพเลอร์ เพื่อลบ...

การกำจัดโค้ดที่ไม่ได้ใช้งาน

ในทฤษฎีคอมไพเลอร์การกำจัดโค้ดที่ไม่ใช้งาน ( DCE , การลบโค้ดที่ไม่ใช้งาน , การตัดโค้ดที่ไม่ใช้งานหรือการตัดโค้ดที่ไม่ใช้งาน ) เป็นการเพิ่มประสิทธิภาพของคอมไพเลอร์เพื่อลบโค้ดที่ไม่ใช้งาน (โค้ดที่ไม่ส่งผลต่อผลลัพธ์ของโปรแกรม) การลบโค้ดดังกล่าวมีประโยชน์หลายประการ ได้แก่ การลด ขนาด ของโปรแกรม (ซึ่งเป็นสิ่งสำคัญในบางบริบท) การลดการใช้ทรัพยากร เช่น จำนวนไบต์ที่จะถ่ายโอน[ 1 ]และช่วยให้โปรแกรมที่กำลังทำงานหลีกเลี่ยงการดำเนินการ ที่ไม่เกี่ยวข้อง ซึ่งจะช่วยลดเวลาในการทำงาน นอกจากนี้ยังสามารถเปิดใช้งานการเพิ่มประสิทธิภาพเพิ่มเติมได้โดยการทำให้โครงสร้างของโปรแกรมง่ายขึ้น โค้ดที่ไม่ใช้งานรวมถึงโค้ดที่ไม่สามารถดำเนินการได้เลย ( โค้ดที่เข้าถึงไม่ได้ ) และโค้ดที่ส่งผลต่อ ตัวแปรที่ไม่ใช้งานเท่านั้น(เขียนถึง แต่ไม่เคยอ่านกลับ) กล่าวคือ ไม่เกี่ยวข้องกับโปรแกรม

ตัวอย่าง

พิจารณาตัวอย่างต่อไปนี้ซึ่งเขียนด้วยภาษา C

int foo ( void ) { int a = 24 ; int b = 25 ; // กำหนดค่าให้กับตัวแปรที่ไม่มีการใช้งานint c ; c = a * 4 ; return c ; b = 24 ; // โค้ดที่ไม่สามารถเข้าถึงได้return 0 ; }

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

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

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

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

การกำจัดโค้ดที่ไม่ได้ใช้งาน (dead-code elimination) มักใช้เป็นทางเลือกแทนการรวมโค้ดที่ไม่จำเป็น (optional code inclusion) ผ่านพรีโปรเซสเซอร์ลองพิจารณาโค้ดต่อไปนี้

// ตั้งค่า DEBUG_MODE เป็น false constexpr bool DEBUG_MODE = false ;int main ( void ) { int a = 5 ; int b = 6 ; int c ; c = a * ( b / 2 ); if ( DEBUG_MODE ) { printf ( "%d \n " , c ); } return c ; }

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

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

ในอดีต การกำจัดโค้ดที่ไม่มีประโยชน์จะดำเนินการโดยใช้ข้อมูลที่ได้จากการวิเคราะห์การไหลของข้อมูล[ 3 ]อัลกอริทึมที่ใช้รูปแบบการกำหนดค่าเดียวแบบคงที่ (SSA) ปรากฏในบทความวารสารต้นฉบับเกี่ยวกับ รูปแบบ SSAโดย Ron Cytron และคณะ[ 4 ] Robert Shillingsburg (หรือที่รู้จักในชื่อ Shillner) ได้ปรับปรุงอัลกอริทึมและพัฒนาอัลกอริทึมเสริมสำหรับการกำจัดการดำเนินการควบคุมการไหลที่ไร้ประโยชน์[ 5 ]

การกำจัดโค้ดที่ไม่ได้ใช้งานแบบไดนามิก

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

อย่างไรก็ตาม ในทางปฏิบัติ เป็นเรื่องปกติที่ส่วนของโค้ดจะแสดงถึงโค้ดที่ตายแล้วหรือไม่สามารถเข้าถึงได้ภายใต้เงื่อนไขบางประการ เท่านั้น ซึ่งอาจไม่เป็นที่ทราบในขณะที่ทำการคอมไพล์หรือแอสเซมบลี เงื่อนไขดังกล่าวอาจถูกกำหนดโดยสภาพแวดล้อมรันไทม์ ที่แตกต่างกัน (เช่น ระบบปฏิบัติการเวอร์ชันต่างๆ หรือชุดและการรวมกันของไดรเวอร์หรือบริการที่โหลดในสภาพแวดล้อมเป้าหมายเฉพาะ) ซึ่งอาจต้องการชุดกรณีพิเศษที่แตกต่างกันในโค้ด แต่ในขณะเดียวกันก็กลายเป็นโค้ดที่ตายแล้วตามเงื่อนไขสำหรับกรณีอื่นๆ[ 6 ] [ 7 ]นอกจากนี้ ซอฟต์แวร์ (เช่น ไดรเวอร์หรือบริการแบบถาวร) อาจสามารถกำหนดค่าให้รวมหรือยกเว้นคุณสมบัติบางอย่างได้ขึ้นอยู่กับความต้องการของผู้ใช้ ทำให้ส่วนของโค้ดที่ไม่ได้ใช้ไม่มีประโยชน์ในสถานการณ์เฉพาะ[ 6 ] [ 7 ]แม้ว่าซอฟต์แวร์แบบโมดูลาร์อาจได้รับการพัฒนาเพื่อโหลดไลบรารีแบบไดนามิกตามความต้องการเท่านั้น แต่ในกรณีส่วนใหญ่ การโหลดเฉพาะรูทีนที่เกี่ยวข้องจากไลบรารีใดไลบรารีหนึ่งนั้นเป็นไปไม่ได้ และถึงแม้ว่าจะรองรับได้ รูทีนก็อาจยังมีส่วนของโค้ดที่ถือว่าเป็นโค้ดที่ไม่ได้ใช้งานในสถานการณ์ที่กำหนด แต่ไม่สามารถตัดออกได้ในระหว่างการคอมไพล์

เทคนิคที่ใช้ในการตรวจจับความต้องการแบบไดนามิก ระบุและแก้ไขการพึ่งพา ลบโค้ดที่ตายแล้วแบบมีเงื่อนไข และรวมโค้ดที่เหลือเข้าด้วยกันอีกครั้งเมื่อโหลดหรือรันไทม์เรียกว่าการกำจัดโค้ดที่ตายแล้วแบบไดนามิก[ 8 ] [ 9 ] [ 10 ]หรือการกำจัดคำสั่งที่ตายแล้วแบบไดนามิก[ 11 ]

ภาษาโปรแกรม คอมไพเลอร์ และระบบปฏิบัติการส่วนใหญ่ไม่ให้การสนับสนุนเพิ่มเติมหรือให้การสนับสนุนเพียงเล็กน้อยนอกเหนือจากการโหลดไลบรารีแบบไดนามิกและการเชื่อมโยงแบบล่าช้าดังนั้นซอฟต์แวร์ที่ใช้การกำจัดโค้ดที่ไม่ได้ใช้งานแบบไดนามิกจึงหายากมากเมื่อใช้ร่วมกับภาษาที่คอมไพล์ล่วงหน้าหรือเขียนด้วยภาษาแอสเซมบลี [ 12 ] [ 13 ] [ 14 ] อย่างไรก็ตามการใช้งานภาษาที่ทำการคอมไพล์แบบทันเวลาอาจปรับให้เหมาะสมแบบไดนามิกสำหรับการกำจัดโค้ดที่ไม่ได้ใช้งาน[ 10 ] [ 15 ] [ 16 ]

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

ดูเพิ่มเติม

อ่านเพิ่มเติม

  • Bodík, Rastislav; Gupta, Rajiv (มิถุนายน 1997). "การกำจัดโค้ดที่ไม่ได้ใช้งานบางส่วนโดยใช้การแปลงแบบสไลซ์". รายงานการประชุม ACM SIGPLAN 1997 ว่าด้วยการออกแบบและการใช้งานภาษาโปรแกรม (PLDI '97) : 682– 694.
  • Aho, Alfred Vaino ; Sethi, Ravi ; Ullman, Jeffrey David (1986). คอมไพเลอร์ - หลักการ เทคนิค และเครื่องมือ . สำนักพิมพ์ Addison Wesley . ISBN 0-201-10194-7.
  • Muchnick, Steven Stanley (1997). การออกแบบและการใช้งานคอมไพเลอร์ขั้นสูง . สำนักพิมพ์ Morgan Kaufmann . ISBN 1-55860-320-4.
  • กรูน, ดิ๊ก ; บัล, อองรี แอล ; จาคอบส์, เซเรียล JH; แลงเกนเดน, โคเอน จี. (2000) การออกแบบคอมไพเลอ ร์สมัยใหม่John Wiley & Sons, Inc. ISBN 0-471-97697-0.
  • เคนเนดี, เคน ; อัลเลน, แรนดี (2002). "บทที่ 4.4 การวิเคราะห์การไหลของข้อมูล - บทที่ 4.4.2 การกำจัดโค้ดที่ไม่ได้ใช้งาน" การเพิ่มประสิทธิภาพคอมไพเลอร์สำหรับสถาปัตยกรรมสมัยใหม่: แนวทางตามการพึ่งพา (ฉบับพิมพ์ดิจิทัลปี 2011 ของฉบับพิมพ์ครั้งที่ 1). สำนักพิมพ์ Academic Press / Morgan Kaufmann Publishers / Elsevierหน้า  137 , 145–147 , 167. ISBN 978-1-55860-286-1. ลคซีเอ็น 2001092381 .
  • Muth, Robert; Debray, Saumya K.; Watterson, Scott; De Bosschere, Koen (มกราคม 2001) [1999-11-02]. "alto: ตัวเพิ่มประสิทธิภาพการเชื่อมโยงเวลาสำหรับ Compaq Alpha" ซอฟต์แวร์: การปฏิบัติและประสบการณ์ 31 ( 1): 67– 101. CiteSeerX  10.1.1.33.4933 . doi : 10.1002/1097-024X(200101)31:1<67::AID-SPE357>3.0.CO;2-A . S2CID  442062 .[5]
  • จะหลอกคอมไพเลอร์ C/C++ ให้สร้างโค้ดที่แย่ได้อย่างไร?
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Dead-code_elimination&oldid=1351946253 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ การกำจัดโค้ดที่ไม่ได้ใช้งาน

ใน ทฤษฎีคอมไพเลอร์ การ กำจัดโค้ดที่ไม่ใช้งาน ( DCE , การลบโค้ดที่ไม่ใช้งาน , การตัดโค้ดที่ไม่ใช้งาน หรือ การตัดโค้ดที่ไม่ใช้งาน ) เป็นการ เพิ่มประสิทธิภาพของคอมไพเลอร์ เพื่อลบ...

ตัวอย่าง

พิจารณาตัวอย่างต่อไปนี้ซึ่งเขียนด้วยภาษา C

การกำจัดโค้ดที่ไม่ได้ใช้งานแบบไดนามิก

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

ดูเพิ่มเติม

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