Як ви могли б паралелізувати 2D-імітаційне моделювання


16

Як ви могли запрограмувати 2D-моделювання boid таким чином, щоб воно могло використовувати обробну потужність з різних джерел (кластери, gpu).

приклад боїдів

У наведеному вище прикладі кольорові частинки рухаються навколо, поки вони не скупчуються (жовтіють) і не припиняють рух.

Проблема полягає в тому, що всі сутності можуть потенційно взаємодіяти між собою, хоча суб'єкт у верхньому лівому куті навряд чи взаємодіє з одним у нижньому правому куті. Якщо домен був розділений на різні сегменти, це може прискорити все, але якщо організація захотіла перейти на інший сегмент, то можуть виникнути проблеми.

На даний момент це моделювання працює з 5000 об'єктами з хорошою частотою кадрів, я хотів би спробувати це з мільйонами, якщо це можливо.

Чи можна було б використовувати квадратичні дерева для подальшої оптимізації цього? Будь-які інші пропозиції?


Ви просите про оптимізацію чи як паралелізувати? Це різні речі.
bummzack

@bummzack Як паралелізуватись, я щойно додав подальше пояснення, чи допомагає це?
Sycren

Відповіді:


7

Магістерська робота Паралельне моделювання рідин частинок Маттіаса Лінде може запропонувати деяку інформацію про розподіл даних та алгоритми широкомасштабного моделювання.

Його робота орієнтована на гідродинаміку згладжених частинок , яка для наївного рішення має тенденцію використовувати просторовий хешшер з розміром відра навколо розміру сліду ядра частинок при моделюванні.

Оскільки відстань взаємодії важко зафіксована у типових ядрах SPH, такі оптимізації розділення майже важливі для масштабування системи.


хороший папір, але обвинувальна частина щодо цього питання, здається, дуже схожа на відповідь @Fxlll
Ali1S232

Я б сказав, що фактична частина статті полягає в тому, як вона вирішує крайові випадки, вводячи протокол комунікації, ось ця важка частина, квадророзділ є досить очевидним і сам по собі не вирішує крайню проблему.
Майк Семдер

4

Термін, який я дізнався давно, - це швидкість гри в грі.

Якщо швидкість ваших боїдів дорівнює 1, і вони піклуються лише про своїх сусідів, то швидкість інформації - 3, тобто боїд, який знаходиться на відстані двох квадратів від вас, може бути в межах діапазону, який ви дбаєте в межах одного кадру:

1 квадратний рух на боїд у взаємодії (1 + 1) плюс відстань, яку ви можете помітити, речі (1) дорівнює 3.

Враховуючи це, ми дізнаємось, що ми можемо скласти карту на шматки, розмірами яких ми маємо менше, але при цьому швидкість інформації перетинається на будь-які сусідні шматки.

Я припускаю, що ви дозволяєте вашим бонусам рухатись лише однією площею, але вони можуть бачити три

Якщо ви хочете запустити масивну паралельну сим, ви збиваєтеся в сітки 10х10, але перетинаєтесь на 5 квадратів на кожному краї. Щоразу, коли хтось із ваших опиняється в межах інформаційної відстані від краю місцевого шматка, вам слід оновити сусіда, і коли вони перейдуть межу, вони не належать вам. Якщо сусід каже, що боїд, який вони контролюють, перемістився у ваш шматок, ви повинні перейняти його AI.

Це означає, що комунікація локалізована для сусідніх менеджерів, а трафік зводиться до мінімуму. Чим більше завдань ви виконуєте, тим більше процесорів ви можете використовувати для живлення імітації, але чим більше ви виконуєте завдання, тим більше їх накладається, а отже, чим більше інформації проходить між завданнями / кусками в міру просування моделювання. Тут вам потрібно отримати важку руку і настроїти розмір шматка, виходячи зі складності AI та наявного обладнання.


уявіть, що в світі є сітка 1000 000х1000 000, а в світі є 10 000 000 боїдів, і кожен боїд може рухатися рівно по одному квадрату на кожен виток, чи можете ви пояснити, як перевірити, чи є боїд в сусідньому сусідстві?
Ali1S232

Я здогадуюсь, що ми можемо розділити його на 2000 квадратів 500х500 або більше. кожен квадрат містить список суми, а також список сусідів. Якщо боїд виходить із квадрата, він видаляється зі списку боїдів та додається до іншого квадрата. Проблема з цим методом, яку я бачу, полягає в тому, якщо ви додасте щось із флексом, який більший за квадрат. рішення квадратури повинно бути динамічним, але я не впевнений, наскільки це дорого
Sycren

@Gajet: вам потрібно лише перевірити, чи немає у вас пошкоджень у вашій групі чи кордонах сусіда. Пам'ятайте, що кордон гарантується дизайном, щоб врахувати, наскільки далеко може рухатися будь-яка організація плюс відстань, яку можуть бачити суб'єкти. @Sycren: зграя, хоча нам здається, що це велика сутність, все ще є лише невеликим масштабним ефектом. Школа школи не слідує за школою, вони слідують за своїми спостережуваними сусідами.
Річард Фабіан

2

Читаючи свій запитання, схоже, ви можете скористатися квадратичними деревами, створити квадрове дерево і запустити моделювання для кожного сегмента на різному блоці обробки. Це призведе до того, що перевірка трапляється лише з предметами, розташованими поруч. але вам потрібно синхронізувати потоки кожного циклу. Що означає передати деякі з цих боїдів з однієї групи обробки в іншу. загалом кожен цикл буде складатися з 3 етапів:

  1. Перемістіть усі боїди на одне ціле. (яку можна легко обробити за допомогою декількох потоків)
  2. Призначення кожної боїди до групи *. Це означає, що використовуючи алгоритм O (n), ви повинні вибрати, які боїди, швидше за все, можуть зіткнутися. З цим також можна впоратися за допомогою декількох потоків.
  3. Зрештою, ви повинні перевірити, чи відбулися зіткнення двох боїдів в одній групі.

* Для створення груп ви можете використовувати схему нижче:

введіть тут опис зображення

зауважте, що деякі боїди можуть входити до декількох груп, але ця модель дає більш точні результати. Ви також можете створити стільки груп, скільки Ви хочете, використовуючи цю схему, це просто число, яке Ви повинні знайти для кількості файлів і екрану, який розмір екрана, яка найкраща кількість груп, які Вам потрібно створити.

--edit--

є ще одне уявлення про сегментацію, яке описано в статті @LarsViklund, підсумований, таким чином, набагато менше подвійних перевірок і немає необхідності збільшувати / зменшувати кількість потоків між кроками:

введіть тут опис зображення

зауважимо, що деякі райони все ще є частиною двох груп. і ширина площі обох груп покриття рівно 2*maximum speed. У вашому випадку, якщо боїди переміщують один піксель за крок моделювання, вам потрібно розділити лише 2 пікселя по ширині між кожною 2 групою. і є невелика площа, яка входить до складу 4 груп. але в цілому цей спосіб легше здійснити і набагато швидше, якщо він реалізований правильно. і, до речі, немає зворотного руху таким чином, якщо якийсь об'єкт може переміститися, він може переміститися, більше перевірки не потрібно.


Здається, що це гарна ідея, але перед тим, як перейти до кроку 1, мені потрібно буде виявити зіткнення, щоб побачити, чи можуть вони рухатися, чи не так?
Sycren

Ви можете перемістити їх, а потім перевірити, чи не відбудеться зіткнення в зворотному русі (для такої точної передачі), якщо не дозволить моделювання продовжуватися.
Ali1S232

Дякую, це має більше сенсу. Окрім квадри, ви можете придумати будь-який інший спосіб розділити навантаження?
Sycren

Як ви бачите, мої сегментації не є повністю квадратичним деревом, у нього є ще одна додаткова група для підвищення точності, стиль квадрового дерева просто набагато простіше в обробці. Залежно від світового розміру, ви можете додати більше груп, що означає менше перевірки в кожному циклі. це компроміс між пам’ятним споживанням і швидкістю обчислень. і це не обов'язково повинно бути одним потоком для кожної групи. Ви можете мати кілька потоків для обчислення декількох груп. Ви також можете розділити обчислення груп між двома або більше потоками.
Ali1S232

@Gajet, якщо я правильно розумію вашу картину, було б багато подвійних обчислень, оскільки ділянки груп, що перекриваються, дуже великі. Зважаючи на те, що питання задають, щоб імітувати до декількох мільйонів балів, це було б величезною тратою.
Майк Семдер

2

Нещодавно я вирішив цю проблему, використовуючи деякі з цих відповідей як вихідну точку. Найкорисніше, що потрібно пам’ятати, - це те, що боїди - це щось просте моделювання n-тіла: кожен боїд - це частинка, яка чинить силу на своїх сусідів.

Мені було важко читати папір Лінде; Я пропоную замість цього переглянути "Швидкі паралельні алгоритми для молекулярної динаміки короткого діапазону" SJ Plimpton , на які посилався Лінде. Папір Плімптона набагато легше читати і деталізувати з кращими цифрами:

У двох словах, способи декомпозиції атомів присвоюють підмножину атомів постійно кожному процесору, методи декомпозиції присвоюють підмножину обчислень подвійних силових обчислень кожному методу, а просторові методи декомпозиції присвоюють підрегіон вікна імітації кожному проц. .

Я рекомендую спробувати AD. Це найпростіше зрозуміти та реалізувати. FD дуже схожий. Ось моделювання nVidia n-body з CUDA за допомогою FD, яке повинно дати вам приблизне уявлення про те, як плитка та скорочення можуть допомогти кардинально перевершити серійні показники.

Реалізація SD, як правило, є оптимізаційними методами і вимагає певної міри хореографії для їх здійснення. Вони майже завжди швидші і краще масштабуються.

Це пояснюється тим, що AD / FD вимагає складання "сусідського списку" для кожного boid. Якщо кожен боїд повинен знати положення своїх сусідів, зв'язок між ними - O ( n ²). Ви можете використовувати списки сусідів Verlet, щоб зменшити розмір області, яку перевіряє кожен boid, що дозволяє переробляти список кожні кілька кроків часу замість кожного кроку, але це все одно O ( n ²). У SD кожна комірка зберігає список сусідів, тоді як в AD / FD кожен боїд має список сусідів. Отже, замість того, щоб кожен боїд спілкувався один з одним, кожна клітина спілкувалася між собою. Це зниження комунікацій - це те, звідки відбувається збільшення швидкості.

На жаль, проблеми з саботажем SD незначно. Наявність у кожного процесора відстеження комірки є найбільш вигідним, коли боїди дещо рівномірно розподілені по всій області. Але ви хочете, щоб боїди збиралися разом! Якщо ваша зграя поводиться належним чином, переважна більшість ваших процесорів буде відмічати, обмінюючись порожніми списками один з одним, і невелика група комірок в кінцевому підсумку виконає ті самі розрахунки, що і AD або FD.

Щоб вирішити це, ви можете або математично налаштувати розмір комірок (який є постійним), щоб мінімізувати кількість порожніх комірок у будь-який момент часу, або використовувати алгоритм Барнса-Хата для чотирьох дерев. Алгоритм BH надзвичайно потужний. Як не парадоксально, але це надзвичайно важко реалізувати на паралельних архітектурах. Це тому, що дерево БХ нерегулярне, тому паралельні нитки будуть проходити по ньому з дивовижною різною швидкістю, що призводить до розбіжності ниток. Лосось та Дубінський представили ортогональні рекурсивні алгоритми поділу для рівномірного розподілу кватрелів серед процесорів, які повинні бути повторно перетворені для більшості паралельних архітектур.

Як бачимо, ми зараз чітко в області оптимізації та чорної магії. Знову ж таки спробуйте прочитати папір Плімптона і побачити, чи має це сенс.


1

Я припускаю, що ваша - це тороїдальна система, ви можете розділити простір, щоб кожен блок мав свою піддіона.

На кожному кроці частинки переміщуються, частинки, що виходять з піддіапазону, відправляються у відповідний процесор; на кроці зв'язку буде синхронізовано процесори, і буде зроблено останній крок для розробки положення сторонніх частинок (якщо вони є).

Тут є три проблеми:

  • 1) форма підрайону:

Можна вибрати прямокутники, але показувати невелике співвідношення площа / периметр у порівнянні з колами. Чим більша межа, тим більше частинок залишиться. У той час як цикли демонструють найкраще співвідношення A / p, його не можна використовувати для тесселяції, тому вам слід визначити деяку (можливо напіврегулярну) тесселяцію з хорошим середнім співвідношенням A / p. Очевидно, що обчислення індексу пензлика за координатою комірок повинно бути простим, тому врахуйте це, перш ніж спробувати дуже екзотичну китицю.

  • 2) комунікаційнийпротокол:

Залежно від того, яку інфраструктуру зв'язку ви маєте, ви можете думати, як розкинути інформацію про перетин кордону між процесорами. Відновлення мовлення проти однорангових та відновлення однорангових - це всі варіанти.

  • 3) Виділення підрайону:

Ви повинні підтримувати розробку збалансованою, оскільки на кожному кроці відбувається синхронізація. Ви можете статично або динамічно розподіляти області для процесорів. Це не є великою проблемою, якщо ваш простір однозначно охоплений активними частинками, але я вірю, що в цьому випадку це може бути неправдою, оскільки зіткнення деактивують частинки. Зміна розподілу вимагає більш важкого кроку зв'язку; деякі ярлики можуть бути прийняті, якщо всі процесори діляться транскордонною інформацією, але вам доведеться трохи розглянути це


@Fxlll Я не впевнений, що ти маєш на увазі під тороїдальною системою, вона не має форми пончика. Ви маєте на увазі, якщо частинка відходить від правої частини, вона з’являється знову з лівої? Якщо так, це не так, якщо частинка потрапляє в праву частину, вона намагається рухатись в іншому напрямку.
Sycren

@Sycren гаразд, у цьому випадку вам доведеться подумати про те, як обмацувати та обробляти область на краю особливим чином
FxIII

-1

Спробуйте моє моделювання ключів https://github.com/wahabjawed/Boids-Simulation

Я розробив це на XNA


Просто посилання на повний проект не є гарною відповіддю. Читач змушений копати ваше джерело до тих пір, поки не знайде частину, що відповідає питанню, а потім все ще повинен зрозуміти, як воно вирішує проблему. Чи можете ви, будь ласка, описати простою англійською мовою, як ви підійшли до проблеми та які переваги вона має над рішеннями, описаними в інших відповідях? Ви можете скопіювати та вставити кілька коротких фрагментів коду у свою відповідь, якщо вони допоможуть зрозуміти ваш опис.
Філіп
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.