การจัดการหน่วยความจำในการเขียนโปรแกรมกลายเป็นปัญหาที่ไม่เกี่ยวข้องหรือไม่?


38

ความเป็นมา
ฉันเยี่ยมชมเว็บไซต์เก่า (แต่ยอดเยี่ยม) ที่ฉันไม่เคยไปมานานหลายปี - Alioth Language Shootout ( http://benchmarksgame.alioth.debian.org/ )

ฉันเริ่มเขียนโปรแกรมใน C / C ++ หลายปีที่ผ่านมา แต่หลังจากนั้นก็ทำงานใน Java โดยเฉพาะเนื่องจากข้อ จำกัด ทางภาษาในโครงการที่ฉันเข้าร่วมไม่จำตัวเลขได้ฉันต้องการเห็นประมาณว่า Java ดีแค่ไหน อาการเทียบกับ C / C ++ ในแง่ของการใช้ทรัพยากร

เวลาการดำเนินการยังคงค่อนข้างดีกับ Java ที่เลวร้ายที่สุดที่มีประสิทธิภาพ 4x ช้ากว่า C / C ++ แต่ในรอบเฉลี่ย (หรือต่ำกว่า) 2x เนื่องจากลักษณะของการนำ Java มาใช้เองจึงไม่แปลกใจเลยและเวลาในการแสดงนั้นต่ำกว่าที่ฉันคาดไว้จริงๆ

อิฐจริงคือการจัดสรรหน่วยความจำ - ที่แย่ที่สุดคือ Java จัดสรร:

  • หน่วยความจำมหันต์ 52x มากกว่า C
  • และ 25x มากกว่า C ++

หน่วยความจำ 52 เท่า ... น่ารังเกียจใช่มั้ย ... หรือมันคืออะไร? หน่วยความจำราคาถูกตอนนี้

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

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


32
อย่าลืมว่าเพียงเพราะ Java จัดสรรหน่วยความจำให้มากกว่า 52 เท่าสำหรับมาตรฐานขนาดเล็กมันไม่ได้หมายความว่ามันจะใช้หน่วยความจำมากขึ้น 52x สำหรับแอปพลิเคชันขนาดใหญ่ ส่วนแบ่งของหน่วยความจำนั้นจะเป็นจำนวนเงินที่แน่นอนโดย JVM และยิ่งใบสมัครของคุณใหญ่ขึ้นเท่าไรก็ยิ่งมีความสำคัญน้อยลงเท่านั้น
Carson63000

4
หากการพัฒนามือถือไม่เกี่ยวข้องกว่าใช่
JeffO

3
คำถามคือว่ามาตรฐาน Java เทียบกับ C / C ++ แย่แค่ไหนและมันมีความหมายอย่างไรในแง่ของการเลือกระหว่างสองภาษา ฉันเห็นสิ่งนี้ว่าเป็นหัวข้อที่เกี่ยวข้องกับโปรแกรมเมอร์ทั้งหมดชัดเจนมุ่งเน้นและสามารถตอบได้อย่างสมเหตุสมผลในรูปแบบปัจจุบัน ฉันโหวตให้เปิดใหม่อีกครั้ง
GlenPeterson

ปัญหาประสิทธิภาพส่วนใหญ่เกิดขึ้นและแก้ไขในระดับการออกแบบไม่ใช่ระดับเครื่องมือ ปัญหาบางอย่างต้องการความละเอียดระดับ 1 มิลลิวินาทีดังนั้นจึงต้องใช้ C / C ++ หากคุณมีระยะทางไกลเช่น 10ms บางที Scala หรือ Java อาจเป็นตัวเลือกที่ดี อินพุตคอนโทรลเลอร์ส่วนใหญ่สำหรับเกมทำงานที่ระดับ 50-100ms หลายคนในทุกวันนี้เขียนหัวข้อที่สำคัญในภาษาหนึ่งและส่วนอื่น ๆ
GlenPeterson

4
เมื่อดูที่ "25x มากกว่า C ++" ในการทดสอบนี้เราต้องคำนึงถึงการเพิ่มขึ้นอย่างต่อเนื่องของรันไทม์ (ประมาณ 13 Mb) เมื่อปัญหาใหญ่ขึ้นความต้องการหน่วยความจำรันไทม์จึงลดลงตามเปอร์เซ็นต์ของโปรแกรมทั้งหมด ในกรณีที่การใช้หน่วยความจำ C ++ น้อยกว่า 1 MB หากคุณลบการใช้หน่วยความจำ C ++ จากการใช้หน่วยความจำ Java คุณจะได้รับค่าคงที่พอสมควร

คำตอบ:


34

การจัดการหน่วยความจำมีความเกี่ยวข้องอย่างเต็มที่เนื่องจากควบคุมว่าสิ่งใดจะปรากฏอย่างรวดเร็วแม้ว่าสิ่งนั้นจะมีหน่วยความจำจำนวนมาก ตัวอย่างที่ดีที่สุดและเป็นที่ยอมรับมากที่สุดคือเกมชื่อ AAA เช่น Call of Duty หรือ Bioshock เหล่านี้เป็นแอปพลิเคชันตามเวลาจริงที่มีประสิทธิภาพซึ่งต้องการการควบคุมจำนวนมากในแง่ของการเพิ่มประสิทธิภาพและการใช้ ไม่ใช่การใช้งานที่เป็นปัญหา แต่เป็นการจัดการ

มีสองคำ: Garbage Collection อัลกอริทึมการรวบรวมขยะอาจทำให้เกิดอาการสะอึกเล็กน้อยในประสิทธิภาพการทำงานหรือแม้แต่ทำให้แอปพลิเคชันหยุดทำงานเป็นเวลาหนึ่งหรือสองวินาที ส่วนใหญ่ไม่เป็นอันตรายในแอปบัญชี แต่อาจทำลายในแง่ของประสบการณ์ของผู้ใช้ในเกม Call of Duty ดังนั้นในแอปพลิเคชั่นที่เวลามีความสำคัญภาษาที่รวบรวมขยะอาจมีปัญหาอย่างมาก เป็นหนึ่งในเป้าหมายการออกแบบของ Squirrel ซึ่งพยายามแก้ไขปัญหาที่ Lua ใช้กับ GC โดยใช้การนับการอ้างอิงแทน

ปวดหัวมากกว่าไหม? แน่นอน แต่ถ้าคุณต้องการการควบคุมที่แม่นยำคุณก็ทนได้


14
-1 "... ถึงตายในเกม ... " - งานประจำวันของฉันคือระบบความปลอดภัยที่มีความสำคัญเช่นเดียวกับความปลอดภัยของชีวิต สิ่งที่เลวร้ายที่สุดที่เกิดขึ้นในซอฟต์แวร์เกมคือผู้เขียนเสียชีวิตเพราะเส็งเคร็งและไม่มีใครซื้อ นี่คือความแตกต่างที่ไม่ควรทำเป็นเรื่องไร้สาระ
mattnz

4
@mattnz คำพูดไม่ดีในส่วนของฉัน มันได้รับการแก้ไขแล้ว ฉันไม่ได้ตั้งใจจะทำอะไรเล็กน้อย
วิศวกรโลก

19
@ Mattatt: ถ้าคุณคุ้นเคยกับเกมเขาเห็นได้ชัดว่าหมายความว่ามันอาจเป็นอันตรายต่อตัวละครของคุณซึ่งเป็นคำพูดที่แท้จริงอย่างสมบูรณ์
Mason Wheeler

8
+1 เพราะผู้ตอบมีเพชรดังนั้นคำตอบจะต้องถูกต้อง
psr

8
นักสะสมขยะแบบเรียลไทม์มีมานานแล้ว
Jörg W Mittag

30

อิฐที่แท้จริงคือการจัดสรรหน่วยความจำ - ที่แย่ที่สุด Java ได้จัดสรรหน่วยความจำให้มากขึ้นกว่า C ถึง 52 เท่าและมากกว่า C ++ อีก 25 เท่า

คุณเข้าใจตัวเลขที่คุณยึดคำถามของคุณหรือไม่

  • มีการจัดสรรหน่วยความจำเท่าใด
  • โปรแกรมกำลังทำอะไรอยู่

เมื่อมีความแตกต่างใหญ่ระหว่างโปรแกรม Java และ C เหล่านั้นส่วนใหญ่เป็นการจัดสรรหน่วยความจำ JVM เริ่มต้นเมื่อเทียบกับ libc ที่ต้องการ:

  • โปรแกรม n-body
    Java 13,996KB :: โปรแกรม C 320KB :: ฟรี Pascal 8KB

ดูงานที่ต้องจัดสรรหน่วยความจำ (หรือใช้บัฟเฟอร์เพิ่มเติมเพื่อสะสมผลลัพธ์จากโปรแกรมมัลติคอร์):

  • mandelbrot
    Java program 67 , 880KB :: C program 30 , 444KB


  • โปรแกรม Java k-nucleotide 494 , 040KB :: C โปรแกรม153 , 452KB


  • โปรแกรม Java reverse-complement 511 , 484KB :: C โปรแกรม248 , 632KB

  • โปรแกรม regex-dna
    Java 557 , 080KB :: C โปรแกรม289 , 088KB


  • โปรแกรม Java -binary 506 , 592KB :: C โปรแกรม99 , 448KB

... การใช้หน่วยความจำควรเป็นสิ่งที่น่ากังวลเมื่อเลือกภาษาที่ใช้งานทั่วไปในวันนี้?

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


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

1
คำตอบที่ดีที่กู้คำถามที่ค่อนข้างยากจน (ระบุรางมาตรฐานคือเลวร้ายยิ่งกว่าการเพิ่มประสิทธิภาพก่อนวัยอันควร :) ข้อมูลที่สนับสนุนการวิเคราะห์นำเสนอได้ดีเป็นรูปธรรมและทำให้อาหารที่ดีสำหรับความคิด คุ้มค่ากับ"คำตอบที่เป็นแบบอย่าง"อย่างแน่นอน
ริ้น

17

เช่นเดียวกับทุกสิ่งมันเป็นการแลกเปลี่ยน

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


8

ขึ้นอยู่กับปัจจัยหลายประการโดยเฉพาะขนาดที่คุณใช้งานอยู่

เพียงเพื่อประโยชน์ของการโต้แย้งเราสมมติว่ามีความแตกต่าง 30x ในหน่วยความจำและ 2x ในการใช้งาน CPU

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

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

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


2
+1 สำหรับการสังเกตขนาด ลองดูที่บทความนี้เพื่อการจัดการทรัพยากรที่มีขนาดใหญ่มาก
Guy Coder

6

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

คุณกำลังทำอะไรผิดถ้าเป็นรหัสของคุณ:

static List<string> Cache;

...
Cache.Add(foo); //and then never remove anything from Cache

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

มันมีความซับซ้อนมากกว่านั้น แต่การรั่วไหลของการอ้างอิงนั้นเหมือนกับว่าเป็นอันตรายมากกว่าการรั่วไหลของหน่วยความจำแบบดั้งเดิม

มีบางสถานที่ที่คุณไม่สามารถเก็บขยะได้ ตัวอย่างเช่น ATTiny84 เป็นไมโครคอนโทรลเลอร์ที่มี 512 ไบต์ของรหัส ROM และ RAM 32 ไบต์ โชคดี! นั่นคือสุดขีดและอาจจะไม่ถูกตั้งโปรแกรมในสิ่งใดนอกจากการชุมนุม แต่ก็ยัง กรณีอื่น ๆ คุณอาจมีหน่วยความจำ 1M แน่นอนว่าคุณสามารถติดตั้งตัวเก็บรวบรวมขยะได้ แต่ถ้าตัวประมวลผลช้ามาก (ไม่ว่าจะด้วยข้อ จำกัด หรือเพื่อรักษาแบตเตอรี่) คุณจะไม่ต้องการใช้ตัวรวบรวมขยะเพราะการติดตามราคาแพงเกินไปสิ่งที่โปรแกรมเมอร์อาจรู้ .

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

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


3

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

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


4
ทัศนคตินี้เป็นวิธีที่เราลงเอยด้วยซอฟต์แวร์ระดับองค์กรที่ป่องบนคอมพิวเตอร์ที่ช้าอย่างไม่น่าเชื่อที่เก็บเพจ ทุกคนบอกว่า 'แน่นอนว่าแอปของฉันใช้หน่วยความจำเพิ่มขึ้น แต่ใครจะห่วงมันฟรีจริง!' แล้วคุณก็จบลงด้วยแอพที่เต็มไปด้วยความทรงจำที่ทำให้หน่วยความจำ 4GB ทำงานช้ากว่าเครื่อง 512MB เมื่อ 10 ปีก่อน
MrFox

@MrFox ที่จริงแล้วปัญหาของซอฟต์แวร์องค์กรคือคนที่ตัดสินใจใช้มันไม่ใช่คนที่ต้องทนทุกข์กับมัน ดูlists.canonical.org/pipermail/kragen-tol/2005-April/000772.htmlสำหรับคำอธิบายที่ยอดเยี่ยมว่าทำไมมันถึงแตก สำหรับส่วนที่เหลือคุณไม่ได้ชี้ให้เห็นว่าบางครั้งการกังวลเกี่ยวกับการใช้หน่วยความจำมีความจำเป็นหรือไม่?
btilly

3

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

นอกจากนี้ยังมีเรื่องของการใช้ประโยชน์จาก GPU แต่บางทีคุณอาจจัดว่าเป็นระบบฝังตัว การคิดอย่างหนักในการใช้ CUDA หรือ OpenCL ช่วยลดปัญหาการจัดการหน่วยความจำในการถ่ายโอนข้อมูลจากหน่วยความจำหลักไปยังหน่วยความจำ GPU


1

เพื่อความเป็นธรรม Java จำนวนมากออกมาตามใจในรูปแบบการระเบิดระดับจริง ๆ และไร้จุดหมายที่ฆ่าการแสดงและความจำหมู แต่ฉันสงสัยว่าหน่วยความจำนั้นเป็นเพียงแค่ JVM ซึ่งในทางทฤษฎี (heh) ให้คุณเรียกใช้ แอพเดียวกันในหลาย ๆ สภาพแวดล้อมโดยไม่ต้องเขียนใหม่ทั้งหมด ดังนั้นข้อเสียของการออกแบบจึงเป็นสิ่งที่ควรคำนึงถึง: "หน่วยความจำผู้ใช้ของคุณนั้นมีความได้เปรียบในการพัฒนาที่คุ้มค่ากับคุณมากแค่ไหน"

นี่คือ IMO การแลกเปลี่ยนที่คุ้มค่าและสมเหตุสมผลอย่างสมบูรณ์แบบเพื่อพิจารณา สิ่งที่ทำให้ฉันสับสนคือความคิดที่ว่าเพราะพีซีสมัยใหม่นั้นทรงพลังและหน่วยความจำราคาถูกมากเราสามารถเพิกเฉยต่อความกังวลและฟีเจอร์ของ bloat และ bloat code และขี้เกียจเกี่ยวกับตัวเลือกจนถึงจุดที่ดูเหมือนสิ่งต่างๆ ฉันใช้ Windows PC แล้วใช้เวลานานเท่าที่เคยทำใน Window '95 อย่างจริงจังว่า Word? จำนวนอึใหม่ที่ 80% ของฐานผู้ใช้ของพวกเขาต้องการจริง ๆ แล้วสามารถเพิ่มได้ใน 18 ปี? ค่อนข้างแน่ใจว่าเรามีระบบตรวจการสะกดล่วงหน้าหน้าต่างใช่มั้ย แต่เรากำลังพูดถึงความทรงจำที่ไม่จำเป็นต้องเร่งความเร็วถ้าคุณมีมันมากมายฉันเลยพูดนอกเรื่อง

แต่แน่นอนถ้าคุณสามารถทำให้แอปเสร็จภายใน 2 สัปดาห์โดยอาจเพิ่มเมกะไบต์สักสองสามตัวแทนที่จะใช้เวลา 2 ปีเพื่อรับรุ่นที่ต้องการเพียงอย่างเดียวไม่กี่ K มันคุ้มค่าที่จะพิจารณาเปรียบเทียบกับ megs สองสามตัว ( ฉันคาดเดา) 4-12 gigs ในเครื่องผู้ใช้ทั่วไปก่อนที่จะเย้ยหยันความคิดที่ว่ามันเลอะเทอะมาก

แต่สิ่งนี้เกี่ยวข้องกับสกาล่านอกเหนือจากคำถามที่เสียไปหรือไม่ เพียงเพราะมันคือการเก็บขยะไม่ได้หมายความว่าคุณไม่ควรพยายามคิดเกี่ยวกับการไหลของข้อมูลในแง่ของสิ่งที่อยู่ในขอบเขตและการปิดและไม่ว่ามันจะถูกทิ้งไว้นั่งหรือใช้ในลักษณะที่มันจะเป็น ยกเลิกการจัดสรรโดย GC เมื่อไม่ต้องการใช้อีกต่อไป นั่นคือสิ่งที่แม้แต่เราผู้พัฒนาเว็บ UI UI ของ JavaScript ก็ต้องคิดและหวังว่าจะยังคงดำเนินต่อไปเมื่อเราแพร่กระจายไปยังโดเมนที่มีปัญหาอื่น ๆ เช่นมะเร็งที่เข้าใจผิด (ซึ่งคุณทุกคนน่าจะฆ่าด้วย Flash หรือ Applets ที่เราเป็น


0

การจัดการหน่วยความจำในการเขียนโปรแกรมกลายเป็นปัญหาที่ไม่เกี่ยวข้องหรือไม่?

การจัดการหน่วยความจำ (หรือการควบคุม) เป็นเหตุผลหลักที่ฉันใช้ C และ C ++

หน่วยความจำราคาถูกตอนนี้

หน่วยความจำไม่เร็ว เรายังคงดูทะเบียนจำนวนน้อยเช่นแคชข้อมูล 32KB สำหรับ L1 ใน i7, 256KB สำหรับ L2 และ 2MB สำหรับ L3 / core ที่กล่าวว่า:

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

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

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

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

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

ป้อนคำอธิบายรูปภาพที่นี่

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

ฉันได้ออกแบบและติดตั้งระบบตาข่ายจำนวนมากในช่วงสองสามทศวรรษที่ผ่านมาและความเร็วของพวกเขามักจะแปรผันตามการใช้หน่วยความจำของพวกเขา แม้ว่าฉันจะทำงานด้วยความทรงจำมากกว่าตอนที่ฉันเริ่มระบบตาข่ายใหม่ของฉันเร็วกว่าการออกแบบครั้งแรกของฉันมากกว่า 10 เท่า (เกือบ 20 ปีที่แล้ว) และในระดับที่สูงเพราะพวกเขาใช้เวลาประมาณ 1 ใน 10 ของ ความทรงจำ. รุ่นใหม่ล่าสุดใช้การบีบอัดแบบมีดัชนีเพื่อบีบอัดข้อมูลให้ได้มากที่สุดและแม้จะมีการประมวลผลการบีบอัด แต่การบีบอัดนั้นเพิ่มประสิทธิภาพได้จริงเพราะอีกครั้งเรามีหน่วยความจำที่รวดเร็วมีค่าเพียงเล็กน้อย ตอนนี้ฉันสามารถใส่ตาข่ายโพลิกอนหนึ่งล้านเส้นที่มีพิกัดพื้นผิวการสร้างขอบวัสดุการกำหนดวัสดุ ฯลฯ พร้อมกับดัชนีเชิงพื้นที่สำหรับประมาณ 30 เมกะไบต์

นี่คือต้นแบบที่ไม่แน่นอนที่มี quadrangles มากกว่า 8 ล้านและรูปแบบการแบ่ง multires บน i3 ที่มี GF 8400 (นี่คือเมื่อหลายปีก่อน) มันเร็วกว่ารุ่นที่ไม่เปลี่ยนรูปของฉัน แต่ไม่ได้ใช้ในการผลิตเนื่องจากฉันพบว่าเวอร์ชันที่ไม่เปลี่ยนรูปได้ง่ายกว่ามากในการดูแลรักษาและประสิทธิภาพในการทำงานก็ไม่เลวร้ายนัก โปรดทราบว่าโครงลวดไม่ได้บ่งบอกถึง facets แต่ patch (สายเป็นเส้นโค้งจริงมิฉะนั้นตาข่ายทั้งหมดจะเป็นสีดำทึบ) แม้ว่าจุดทั้งหมดใน facet จะถูกแก้ไขโดยแปรง

ป้อนคำอธิบายรูปภาพที่นี่

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

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

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

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