คุณจะขนานกับการจำลองแบบ 2 มิติได้อย่างไร


16

คุณจะตั้งโปรแกรมการจำลองแบบสองมิติได้อย่างไรในแบบที่มันสามารถใช้พลังการประมวลผลจากแหล่งต่าง ๆ (กลุ่ม, GPU)

ยกตัวอย่างเช่น

ในตัวอย่างด้านบนอนุภาคที่ไม่มีสีจะเคลื่อนที่ไปรอบ ๆ จนกว่าพวกมันจะรวมกลุ่ม (สีเหลือง) และหยุดเคลื่อนที่

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

ในขณะนี้การจำลองนี้ใช้งานได้กับ 5,000 หน่วยงานที่มีอัตราเฟรมที่ดีฉันต้องการที่จะลองกับคนนับล้านถ้าเป็นไปได้

เป็นไปได้ไหมที่จะใช้ต้นไม้รูปสี่เหลี่ยมเพื่อเพิ่มประสิทธิภาพนี้ ข้อเสนอแนะอื่น ๆ ?


คุณกำลังขอการเพิ่มประสิทธิภาพหรือวิธีการขนาน? สิ่งเหล่านี้แตกต่างกัน
bummzack

@bummzack วิธีการขนานฉันเพิ่งเพิ่มคำอธิบายเพิ่มเติมว่าจะช่วยได้อย่างไร
Sycren

คำตอบ:


7

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

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

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


กระดาษที่ดี แต่ส่วนที่เกี่ยวกับคำถามนี้ดูเหมือนจะเป็นจำนวนมากเช่น @Fxlll คำตอบ
Ali1S232

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

4

คำที่ฉันเรียนรู้เมื่อนานมาแล้วคือความเร็วของข้อมูล

หากความเร็วในการรับของคุณเป็น 1 และพวกเขาสนใจแค่เพื่อนบ้านของพวกเขาแล้วความเร็วของข้อมูลคือ 3 นั่นก็คือ boid ที่อยู่ห่างออกไปสองช่องจากคุณอาจอยู่ในช่วงที่คุณสนใจภายในกรอบเดียว:

1 การเคลื่อนไหวแบบสี่เหลี่ยมจัตุรัสต่อ boid ในการโต้ตอบ (1 + 1) บวกระยะทางที่คุณสามารถสังเกตเห็นสิ่งต่าง ๆ (1) เท่ากับ 3

เมื่อได้รับสิ่งนี้เราเรียนรู้ว่าเราสามารถแยกแผนที่ออกเป็นชิ้นเล็ก ๆ เท่าที่เราต้องการ แต่ด้วยความเร็วของข้อมูลนี้ซ้อนทับกับชิ้นส่วนที่อยู่ใกล้เคียง

ฉันจะสมมติว่าคุณอนุญาตให้ boids ของคุณเคลื่อนที่เพียงหนึ่งตาราง แต่พวกเขาเห็นสามตัว

หากคุณต้องการเรียกใช้ซิมขนานขนาดใหญ่คุณจะหลุดไปเป็น 10x10 กริด แต่ทับซ้อนกัน 5 ช่องบนแต่ละขอบ เมื่อใดก็ตามที่หนึ่งของคุณอยู่ในระยะข้อมูลจากขอบของชิ้นคุณควรปรับปรุงเพื่อนบ้านและเมื่อพวกเขาข้ามเขตแดนพวกเขาไม่ได้เป็นของคุณ หากเพื่อนบ้านบอกว่า boid พวกเขาเป็นผู้ควบคุมได้ถูกย้ายเข้าไปในกลุ่มของคุณคุณต้องรับช่วงต่อมาคือ AI

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


จินตนาการว่าโลกมี 1,000,000x1,000,000 กริดและมี 10,000,000 boids ในโลกและแต่ละ boid สามารถเคลื่อนที่ได้แค่หนึ่งสแควร์ในแต่ละเทิร์นคุณสามารถอธิบายวิธีตรวจสอบว่ามี boid ในละแวกอื่นหรือไม่
Ali1S232

ฉันเดาว่าเราสามารถแบ่งมันเป็น 2,000 500x500 กำลังสองหรือมากกว่า แต่ละตารางประกอบด้วยรายการ boids รวมถึงรายการเพื่อนบ้าน หาก boid ออกจากช่องสี่เหลี่ยมมันจะถูกลบออกจากรายการ boids และเพิ่มเข้าไปในช่องสี่เหลี่ยมอื่น ๆ ปัญหาของวิธีนี้ที่ฉันเห็นคือถ้าคุณเพิ่มบางอย่างด้วย flocking ที่ใหญ่กว่าจตุรัส วิธีการแก้ปัญหาควอดทรีจะต้องเป็นแบบไดนามิก แต่ฉันไม่แน่ใจว่าราคาแพงแค่ไหน
Sycren

@Gajet: คุณเพียงแค่ต้องตรวจสอบ boids ในก้อนของคุณหรือเพื่อนบ้านจัดการชายแดน โปรดจำไว้ว่าเส้นขอบนั้นรับประกันโดยการออกแบบเพื่อพิจารณาว่าเอนทิตีใดที่สามารถเคลื่อนย้ายได้บวกกับระยะทางที่เอนทิตีสามารถมองเห็นได้ @Sycren: ท่านเตือนแม้ว่าดูเหมือนว่าเราจะเป็นองค์กรขนาดใหญ่ แต่ก็ยังคงเป็นเพียงผลขนาดเล็ก โรงเรียนสอนปลาไม่ได้ติดตามโรงเรียนพวกเขาติดตามเพื่อนบ้านที่สังเกตได้
Richard Fabian

2

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

  1. ย้าย boids ทั้งหมดโดยหนึ่งหน่วย (ซึ่งสามารถประมวลผลได้ง่ายโดยใช้หลายเธรด)
  2. มอบหมายให้แต่ละกลุ่มไปที่กลุ่ม * ซึ่งหมายความว่าการใช้อัลกอริทึมของ O (n) คุณต้องเลือกว่า boids ใดที่มีแนวโน้มที่จะทำการชนกันมากที่สุด สิ่งนี้สามารถจัดการได้โดยใช้หลายเธรด
  3. ในท้ายที่สุดคุณต้องตรวจสอบว่าสอง boids ในกลุ่มเดียวกันทำให้เกิดการชนกัน

* ในการสร้างกลุ่มคุณสามารถใช้รูปแบบด้านล่าง:

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

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

--edit--

มีความคิดอื่นเกี่ยวกับการแบ่งส่วนที่อธิบายไว้ในกระดาษ @LarsViklund sugested ด้วยวิธีนี้มีการตรวจสอบสองครั้งน้อยกว่ามากและไม่จำเป็นต้องเพิ่ม / ลดจำนวนเธรดระหว่างขั้นตอน:

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

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


เสียงเหมือนความคิดที่ดี แต่ก่อนที่จะย้ายในขั้นตอนที่ 1 ฉันจะต้องทำการตรวจจับการชนกันเพื่อดูว่าพวกเขาสามารถย้ายได้หรือไม่
Sycren

คุณสามารถย้ายพวกมันจากนั้นตรวจสอบว่ามีการชนใด ๆ เกิดขึ้นหรือไม่ (สำหรับ boid ที่แน่นอนนั้น) หากไม่ปล่อยให้การจำลองดำเนินต่อไป
Ali1S232

ขอบคุณที่ทำให้รู้สึกมากขึ้น นอกเหนือจากควอดทรีคุณสามารถคิดวิธีอื่นเพื่อแยกปริมาณงานได้หรือไม่?
Sycren

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

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

2

ฉันแก้ไขปัญหานี้โดยใช้คำตอบบางข้อเป็นจุดเริ่มต้น สิ่งที่เป็นประโยชน์มากที่สุดที่ต้องจำไว้ก็คือ boids เป็นแบบจำลอง n-body แบบง่าย ๆ : boid แต่ละตัวเป็นอนุภาคที่ออกแรงแรงกับเพื่อนบ้าน

ฉันพบว่ากระดาษ Linde อ่านยาก ฉันขอแนะนำให้ดูที่"ขั้นตอนวิธีเร็วแบบขนานสำหรับพลวัตโมเลกุลระยะสั้นของ SJ Plimptonซึ่ง Linde อ้างถึง กระดาษของ Plimpton นั้นอ่านง่ายและมีรายละเอียดมากขึ้นด้วยตัวเลขที่ดีกว่า:

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

ฉันแนะนำให้คุณลอง AD มันง่ายที่สุดที่จะเข้าใจและนำไปใช้ FD นั้นคล้ายกันมาก นี่คือการจำลองแบบ n-body ของ nVidia กับ CUDA โดยใช้ FD ซึ่งควรให้คุณทราบคร่าวๆว่าการเรียงและลดขนาดสามารถช่วยให้ประสิทธิภาพเหนือกว่าอย่างเห็นได้ชัด

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

นี่คือเนื่องจาก AD / FD ต้องสร้าง "รายชื่อเพื่อนบ้าน" สำหรับแต่ละ boid หากทุกคนต้องการรู้ตำแหน่งของเพื่อนบ้านการสื่อสารระหว่างกันคือ O ( n ²) คุณสามารถใช้รายการ Verlet Neighbour เพื่อลดขนาดของพื้นที่แต่ละเช็ค boid ซึ่งช่วยให้คุณสามารถสร้างรายการทุกสองสามนาทีแทนทุกขั้นตอน แต่ยังคงเป็น O ( n ²) ใน SD แต่ละเซลล์เก็บรายการเพื่อนบ้านใน AD / FD ทุก boid มีรายการเพื่อนบ้าน ดังนั้นแทนที่จะคุยกันทุกคนคุยกันทุกเซลล์สื่อสารกัน การลดลงของการสื่อสารนั้นเป็นที่มาของการเพิ่มความเร็ว

แต่น่าเสียดายที่ปัญหาการก่อวินาศกรรม SD เล็กน้อย การมีตัวประมวลผลแต่ละตัวติดตามเซลล์มีประโยชน์มากที่สุดเมื่อ boids มีการกระจายอย่างเท่าเทียมกันทั่วทั้งภูมิภาค แต่คุณต้องการให้กลุ่มรวมตัวกัน! หากฝูงของคุณทำงานได้อย่างถูกต้องตัวประมวลผลส่วนใหญ่ของคุณจะถูกกำจัดออกไปแลกเปลี่ยนรายการเปล่ากับแต่ละอื่น ๆ และเซลล์กลุ่มเล็ก ๆ จะจบลงด้วยการคำนวณเช่นเดียวกันกับ AD หรือ FD

ในการจัดการกับสิ่งนี้คุณสามารถปรับขนาดของเซลล์ (ซึ่งเป็นค่าคงที่) ทางคณิตศาสตร์เพื่อลดจำนวนเซลล์ว่างในเวลาใดก็ตามหรือใช้อัลกอริทึม Barnes-Hut สำหรับต้นไม้รูปสี่เหลี่ยม อัลกอริทึม BH มีประสิทธิภาพอย่างเหลือเชื่อ ขัดมันเป็นเรื่องยากมากที่จะใช้กับสถาปัตยกรรมแบบขนาน นี่เป็นเพราะต้นไม้ BH ไม่สม่ำเสมอดังนั้นเธรดแบบขนานจะเคลื่อนที่ด้วยความเร็วที่แตกต่างกันอย่างมากทำให้เกิดความแตกต่างของเธรด Salmon และ Dubinski ได้นำเสนออัลกอริทึมแบบแบ่งครึ่งมุมฉากเพื่อกระจาย quadtrees เท่า ๆ กันในโปรเซสเซอร์ซึ่งจะต้องมีการปรับปรุงซ้ำสำหรับสถาปัตยกรรมขนานส่วนใหญ่

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


1

ฉันสมมติว่าคุณเป็นระบบ toroidal คุณสามารถแบ่งพาร์ติชั่นไปยังพื้นที่เพื่อให้แต่ละหน่วยมีพื้นที่ย่อย

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

ที่นี่มีสามปัญหาที่นี่:

  • 1) รูปร่างของพื้นที่ย่อย:

หนึ่งสามารถเลือกสี่เหลี่ยม แต่แสดงอัตราส่วนพื้นที่ / ปริมณฑลขนาดเล็กเมื่อเทียบกับ cirlces ยิ่งเส้นขอบยิ่งมีขนาดใหญ่อนุภาคก็ยิ่งมีขนาดใหญ่ขึ้นเท่านั้น ในขณะที่ cicles แสดงอัตราส่วน A / p ที่ดีที่สุด แต่ไม่สามารถใช้เป็น tessellation ได้ดังนั้นคุณควรจะฝังรากใน tessellation (กึ่งปกติกึ่งปกติ) ที่มีอัตราส่วน A / p เฉลี่ยที่ดี เห็นได้ชัดว่าการคำนวณดัชนีพู่กันโดยการประสานเซลล์ควรง่ายดังนั้นควรพิจารณาเรื่องนี้ก่อนที่จะลองใช้พู่กันแปลกใหม่มาก

  • 2) การสื่อสารช็อกโกแลต:

ขึ้นอยู่กับโครงสร้างพื้นฐานด้านการสื่อสารที่คุณมีคุณสามารถคิดวิธีกระจายข้อมูลข้ามพรมแดนระหว่างโปรเซสเซอร์ การสร้างการกระจายเสียง vs peer-to-peer vs การสื่อสารแบบ peer-to-peer เป็นตัวเลือกทั้งหมด

  • 3) การจัดสรรพื้นที่ย่อย:

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


@ Fxlll ฉันไม่แน่ใจในสิ่งที่คุณหมายถึงโดยระบบ toroidal มันไม่ได้อยู่ในรูปของโดนัท คุณหมายถึงว่าถ้าอนุภาคหลุดไปทางด้านขวามือมันจะปรากฏขึ้นทางด้านซ้ายหรือไม่? ถ้าไม่ใช่อย่างนั้นถ้าอนุภาคเข้ามาทางด้านขวามือมันก็จะเคลื่อนที่ไปในทิศทางที่ต่างออกไป
Sycren

@Sycren ตกลงในกรณีนี้คุณต้องทำพิจารณาบางอย่างเกี่ยวกับ tasselation และรักษาพื้นที่บนขอบในวิธีพิเศษ
FxIII

-1

ลองจำลองของฉันเพื่อหาเบาะแสhttps://github.com/wahabjawed/Boids-Simulation

ฉันพัฒนาสิ่งนี้ใน XNA


เพียงเชื่อมโยงกับโครงการที่สมบูรณ์ไม่ใช่คำตอบที่ดี ผู้อ่านถูกบังคับให้ขุดผ่านแหล่งที่มาของคุณจนกว่าพวกเขาจะพบส่วนที่เกี่ยวข้องกับคำถามและยังต้องเข้าใจว่ามันแก้ปัญหาได้อย่างไร คุณช่วยอธิบายเป็นภาษาอังกฤษธรรมดาได้อย่างไรว่าคุณเข้าถึงปัญหาได้อย่างไรและมีข้อได้เปรียบอะไรบ้างเหนือโซลูชันที่อธิบายไว้ในคำตอบอื่น ๆ คุณสามารถคัดลอกและวางตัวอย่างรหัสสั้น ๆ ไว้ในคำตอบของคุณหากพวกเขาช่วยให้เข้าใจคำอธิบายของคุณ
ฟิลิปป์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.