ฉันควรมีกี่กระทู้และเพื่ออะไร


81

ฉันควรมีเธรดแยกต่างหากสำหรับการเรนเดอร์และตรรกะหรือมากกว่านั้นหรือไม่

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

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


6
แพลตฟอร์มไหน พีซี, NextGen console, สมาร์ทโฟน?
Ellis

มีสิ่งหนึ่งที่ฉันสามารถคิดว่าจะต้องมีหลายเธรด; เครือข่าย
สบู่

ออกจาก exagerations ไม่มี "อันยิ่งใหญ่" ช้าลงเมื่อเกี่ยวข้องกับการล็อค นี่คือตำนานของเมืองและอคติ
v.oddou

คำตอบ:


61

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

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

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

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


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

เช่นเธรดสามารถทำได้โดยไม่ต้องกำหนดเวลางานให้เรียกใช้งานนั้นทันที
jmp97

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

ขออภัยที่ใช้เวลานานกว่าจะกลับมาที่หัวข้อนี้ ฉันไม่ได้สนใจ gamedev เมื่อเร็ว ๆ นี้ นี่อาจเป็นคำตอบที่ดีที่สุดทื่อ แต่ตรงประเด็นและกว้างขวาง
j riv

1
คุณถูกต้องในแง่ที่ว่าฉันไม่สนใจที่จะพูดถึงภาระงานหนักของ I / O การตีความคำถามของฉันคือเกี่ยวกับภาระงานของ CPU เท่านั้น
Jake McArthur

30

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

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

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

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


ระบบที่คุณพูดถึงนั้นคล้ายกับระบบการตั้งเวลาที่ระบุไว้ในคำตอบของ James คนอื่น ๆ ซึ่งยังคงมีรายละเอียดที่ดีในพื้นที่นั้นดังนั้น +1 เช่นเดียวกับที่เพิ่มในการสนทนา
James

3
wiki ชุมชนเกี่ยวกับวิธีตั้งค่าคิวงานและเธรดผู้ทำงานจะดี
bot_bot

23

คำถามนั้นไม่มีคำตอบที่ดีที่สุดเพราะขึ้นอยู่กับว่าคุณพยายามทำอะไร

xbox มีสามคอร์และสามารถจัดการเธรดไม่กี่เธรดก่อนที่การสลับบริบทจะกลายเป็นปัญหา พีซีสามารถจัดการกับอีกไม่กี่อย่าง

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

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

เอ็นจิ้น idTech5 ที่พัฒนาขึ้นสำหรับ Rage ใช้เธรดจำนวนมากจริง ๆ และทำเช่นนั้นโดยแบ่งงานเกมออกเป็น 'งาน' ที่ประมวลผลด้วยระบบ tasking เป้าหมายที่ชัดเจนของพวกเขาคือทำให้เอ็นจิ้นเกมของพวกเขาดีขึ้นเมื่อจำนวนคอร์ของระบบเกมโดยเฉลี่ยกระโดด

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

มันขึ้นอยู่กับเป้าหมายสุดท้ายของคุณ


+1 สำหรับการกล่าวขวัญของระบบการตั้งเวลา .. มักจะเป็นสถานที่ที่ดีไปยังศูนย์สื่อสารด้าย / ระบบ :)
เจมส์

ทำไมถึงลงคะแนน downvoter?
jcora

12

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

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

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


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

2
+1: คำตอบที่ดีที่สุดที่นี่ ฉันจะใช้โครงสร้างที่เป็นนามธรรมมากกว่า threadpools (ตัวอย่างเช่นคิวงานและคนงาน) ถ้ากรอบงานของคุณอนุญาต มันง่ายกว่าที่จะคิด / โปรแกรมในเทอมนี้มากกว่าในเธรดบริสุทธิ์ / ล็อค / ฯลฯ บวก: การแยกเกมของคุณในการเรนเดอร์ลอจิก ฯลฯ นั้นเป็นเรื่องไร้สาระเนื่องจากการเรนเดอร์ต้องรอตรรกะเพื่อให้เสร็จ สร้างงานที่สามารถดำเนินการแบบขนานได้จริง (ตัวอย่าง: คำนวณ AI สำหรับหนึ่ง npc สำหรับเฟรมถัดไป)
Dave O.

@DaveO จุด "บวก" ของคุณเป็นจริงดังนั้น
วิศวกร

11

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

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

  2. กำหนดเวลาการเข้าถึงข้อมูลที่ชัดเจน คุณสามารถแยกติ๊กหลักของคุณออกเป็นระยะ x หากคุณแน่ใจว่า Thread X อ่านข้อมูลในเฟสที่ระบุเท่านั้นคุณยังทราบด้วยว่าเธรดอื่นสามารถแก้ไขข้อมูลได้ในเฟสอื่น

  3. ดับเบิลบัฟเฟอร์ข้อมูลของคุณ นั่นเป็นวิธีที่ง่ายที่สุด แต่เพิ่มเวลาแฝงเนื่องจาก Thread X ทำงานกับข้อมูลจากเฟรมสุดท้ายขณะที่ Thread Y กำลังเตรียมข้อมูลสำหรับเฟรมถัดไป

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

ในการพิจารณาถึงข้อ จำกัด ของฮาร์ดแวร์คุณควรพยายามไม่ทำการสมัครสมาชิกเกินฮาร์ดแวร์ของคุณ ด้วยการสมัครสมาชิกเกินฉันหมายถึงมีเธรดซอฟต์แวร์มากกว่าเธรดฮาร์ดแวร์แพลตฟอร์มของคุณ โดยเฉพาะอย่างยิ่งกับสถาปัตยกรรม PPC (Xbox360, PS3) การสลับงานมีราคาแพงมาก แน่นอนว่าไม่เป็นไรถ้าคุณมีเธรดที่ไม่ได้สมัครสมาชิกจำนวนมากซึ่งจะถูกเรียกใช้ในเวลาเพียงเล็กน้อย (เช่นเฟรมเดียว) หากคุณกำหนดเป้าหมายพีซีคุณควรจำไว้ว่าจำนวนแกนประมวลผล (หรือ HW ที่ดีกว่า - เธรด) มีการเติบโตอย่างต่อเนื่องดังนั้นคุณต้องการค้นหาโซลูชันที่ปรับขนาดได้ซึ่งใช้ประโยชน์จาก CPU-Power เพิ่มเติม ดังนั้นในพื้นที่นี้คุณควรพยายามออกแบบรหัสของคุณตามงานให้มากที่สุด


3

กฎทั่วไปของหัวแม่มือสำหรับเธรดแอปพลิเคชัน: 1 เธรดต่อ CPU Core บนพีซีแบบ quad core ที่หมายถึง 4 ดังที่ได้กล่าวไว้ XBox 360 มี 3 คอร์ แต่ 2 เธรดฮาร์ดแวร์แต่ละเธรดดังนั้น 6 เธรดในกรณีนี้ ในระบบเช่น PS3 ... ขอให้โชคดีในหนึ่ง :) ผู้คนยังคงพยายามที่จะคิดออก

ฉันขอแนะนำให้ออกแบบแต่ละระบบเป็นโมดูลที่มีอยู่ในตัวเองซึ่งคุณสามารถทำเกลียวได้หากคุณต้องการ ซึ่งมักจะหมายถึงการมีเส้นทางการสื่อสารที่กำหนดไว้อย่างชัดเจนระหว่างโมดูลและส่วนที่เหลือของเครื่องยนต์ ฉันชอบกระบวนการอ่านอย่างเดียวโดยเฉพาะเช่นการเรนเดอร์และเสียงรวมถึง 'เรามีหรือไม่' กระบวนการเช่นการอ่านอินพุตของผู้เล่นสำหรับสิ่งต่าง ๆ ที่จะถูกเธรด หากต้องการสัมผัสกับคำตอบที่ได้รับจาก AttackHobo เมื่อคุณแสดงผล 30-60fps หากข้อมูลของคุณเป็น 1 / 30th-1 / 60th ของวินาทีนั้นมันจะไม่เบี่ยงเบนความรู้สึกตอบสนองของเกมของคุณ โปรดจำไว้เสมอว่าความแตกต่างที่สำคัญระหว่างแอพพลิเคชั่นซอฟต์แวร์และวิดีโอเกมนั้นทำทุกอย่าง 30-60 ครั้งต่อวินาที ในบันทึกเดียวกันนั้น

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



อา +1 :) ฉันถูก จำกัด เสมอไปยังพื้นที่ที่เครือข่ายของ 360 และ PS3, ฮิฮิ :)
เจมส์

0

ฉันสร้างหนึ่งเธรดต่อหนึ่งโลจิคัลคอร์ (ลบหนึ่งเธรดสำหรับเธรดหลักซึ่งบังเอิญรับผิดชอบการแสดงผล แต่ก็ทำหน้าที่เป็นเธรดผู้ทำงานด้วย)

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

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

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

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

ดูเหมือนว่าจะไม่มีการใช้งานเธรดในระดับที่ยอมรับได้!


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

0

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

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