2D 보이드 시뮬레이션을 병렬화하는 방법


16

다른 소스 (클러스터, GPU)의 처리 능력을 사용할 수있는 방식으로 2D 보이드 시뮬레이션을 프로그래밍하는 방법

보이드 예

위의 예에서 색상이없는 입자는 클러스터 (노란색)가 될 때까지 움직이며 이동을 멈 춥니 다.

문제는 왼쪽 위에있는 개체가 오른쪽 아래에있는 개체와 상호 작용할 가능성은 없지만 모든 개체가 서로 잠재적으로 상호 작용할 수 있다는 것입니다. 도메인이 다른 세그먼트로 분할되면 전체 속도가 빨라질 수 있지만, 엔티티가 다른 세그먼트로 넘어가려면 문제가있을 수 있습니다.

현재이 시뮬레이션은 프레임 속도가 좋은 5000 개의 엔터티에서 작동하지만 가능한 경우 수백만으로 시도하고 싶습니다.

쿼드 트리를 사용하여이를 더욱 최적화 할 수 있습니까? 다른 제안?


최적화 또는 병렬화 방법을 요청하고 있습니까? 이것들은 다른 것입니다.
bummzack

@bummzack 병렬화 방법, 방금 추가 설명을 추가했는데 도움이 되나요?
Sycren

답변:


7

Mattias Linde 의 입자 유체 에 대한 석사 논문의 병렬 시뮬레이션은 대규모 시뮬레이션을위한 데이터 파티셔닝 및 알고리즘에 대한 통찰력을 제공 할 수 있습니다.

그의 논문은 Smoothed-Particle Hydrodynamics 에 적합하며, 순진한 솔루션의 경우 시뮬레이션에서 입자의 커널 풋 프린트 크기 주위에 버킷 크기의 공간 해싱을 사용하는 경향이 있습니다.

상호 작용 거리가 일반적인 SPH 커널에서 고정되어 있기 때문에 이러한 분할 최적화는 시스템을 확장하는 데 거의 필수적입니다.


좋은 논문이지만이 질문에 대한 정확한 부분은 @ Fxlll 답변과 같은 것으로 보입니다.
Ali1S232

이 논문의 실제 부분은 통신 프로토콜을 도입하여 엣지 케이스를 해결하는 방법이며, 어려운 부분은 쿼드 파티셔닝이 명백하고 자체적으로 엣지 케이스 문제를 해결하지 못한다고 말합니다.
Maik Semder

4

오래 전에 배운 용어는 게임의 정보 속도였습니다.

만약 당신의 보이드의 속도가 1이고 그들이 단지 이웃에 대해서만 관심이 있다면, 정보의 속도는 3입니다. 즉, 당신으로부터 2 제곱 떨어진 보이드는 당신이 관심있는 범위 내에있을 수 있습니다 :

교호 작용 (1 + 1)에서 보이드 당 1 제곱 이동에 사물 (1)을 알 수있는 거리가 3과 같습니다.

이를 통해 우리는 맵을 원하는만큼 작은 크기로 조각화 할 수 있지만 이러한 정보 속도를 사용하면 인접한 덩어리에 겹치게됩니다.

나는 당신의 보이드가 한 칸만 움직일 수 있다고 가정하지만, 그들은 3 개를 볼 수 있습니다.

대규모 병렬 시뮬레이션을 실행하려는 경우 10x10 그리드로 청크되지만 각 모서리에 5 제곱이 겹칩니다. 당신의 한쪽이 로컬 청크의 가장자리로부터 정보 거리 내에있을 때마다, 당신은 이웃을 업데이트해야하고, 일단 그들이 경계를 통과하면, 그들은 당신의 것이 아닙니다. 이웃이 통제하는 보이드가 청크로 옮겨 졌다고 말하면 AI를 인수해야합니다.

이는 통신이 인접한 청크 관리자에게 국한되어 트래픽이 최소로 감소됨을 의미합니다. 더 많은 작업을 실행할수록 시뮬레이션에 전원을 공급하는 데 더 많은 CPU를 사용할 수 있지만 더 많은 작업을 실행할수록 중복되는 작업이 많아지고 시뮬레이션이 진행됨에 따라 작업 / 청크 사이에 더 많은 정보가 전달됩니다. AI 복잡성과 사용 가능한 하드웨어를 기반으로 무거운 손을 잡고 청크 크기를 조정해야합니다.


세계가 1,000,000x1,000,000 그리드이고, 세계에 10,000,000 개의 보이드가 있고 각 보이드가 매 턴마다 정확히 1 칸씩 움직일 수 있다고 상상해보십시오.
Ali1S232

우리가 그것을 2000 500x500 사각형 이상으로 나눌 수 있다고 추측합니다. 각 광장에는 보이드 목록과 이웃 목록이 있습니다. 보이드가 정사각형을 벗어나면 보이드 목록에서 제거되고 다른 정사각형에 추가됩니다. 내가 볼 수있는이 방법의 문제는 사각형보다 큰 무리를 짓는 것을 추가하는 것입니다. 쿼드 트리 솔루션은 동적이어야하지만, 얼마나 비쌀 지 모르겠습니다.
Sycren

@Gajet : 청크 또는 인접 관리되는 테두리의 보이드 만 확인하면됩니다. 경계는 설계에 의해 엔티티가 얼마나 멀리 이동할 수 있는지와 엔티티가 볼 수있는 거리를 고려하여 보장됨을 기억하십시오. @Sycren : 무리는 비록 우리가 큰 실체 인 것처럼 보이지만 여전히 작은 규모의 효과 일뿐입니다. 물고기 학교는 학교를 따르지 않고 관찰 가능한 이웃을 따릅니다.
Richard Fabian

2

쿼리를 읽음으로써 쿼드 트리를 활용하고, 쿼드 트리를 생성하고, 다른 처리 장치에서 각 세그먼트에 대한 시뮬레이션을 실행할 수 있습니다. 이로 인해 서로 가까이있는 객체에 대해서만 검사가 수행됩니다. 그러나 매 사이클마다 스레드를 동기화해야합니다. 이는 하나의 처리 그룹에서 다른 처리 그룹으로 해당 보이드를 전송한다는 의미입니다. 일반적으로 모든주기는 3 단계로 구성됩니다.

  1. 모든 보이드를 한 단위 씩 움직입니다. (여러 스레드를 사용하여 쉽게 처리 할 수 ​​있음)
  2. 각 보이드를 그룹에 할당 *. 이는 O (n) 알고리즘을 사용하여 충돌을 일으킬 가능성이 가장 높은 보이드를 선택해야 함을 의미합니다. 여러 스레드를 사용하여 처리 할 수도 있습니다.
  3. 결국 같은 그룹에있는 두 개의 보이드가 충돌했는지 확인해야합니다.

* 그룹을 만들려면 아래 패턴을 사용할 수 있습니다.

여기에 이미지 설명을 입력하십시오

일부 보이드는 둘 이상의 그룹에 속할 수 있지만이 패턴은보다 정확한 결과를 제공합니다. 이 패턴을 사용하여 원하는만큼의 그룹을 만들 수도 있습니다.이 화면은 보이드 수와 화면 크기, 화면 크기, 생성해야하는 그룹 중 가장 많은 수에 대해 알아야 할 숫자입니다.

--편집하다--

@LarsViklund가 제안한 논문에 설명 된 세분화에 대한 또 다른 아이디어가 있습니다.이 방법은 이중 검사가 훨씬 적으며 단계 사이의 스레드 수를 늘리거나 줄일 필요가 없습니다.

여기에 이미지 설명을 입력하십시오

일부 영역은 여전히 ​​두 그룹의 일부입니다. 그리고 두 그룹 커버의 넓이는 정확히 2*maximum speed입니다. 귀하의 경우 보이드가 시뮬레이션 단계 당 하나의 픽셀을 이동하면 각 2 그룹 사이에 2 픽셀 너비 영역 만 공유하면됩니다. 그리고 4 개 그룹의 일부인 작은 영역이 있습니다. 그러나 일반적 으로이 방법은 구현하기 쉽고 올바르게 구현하면 훨씬 빠릅니다. 그런데이 방법으로 역 이동이 없으면 어떤 물체가 움직일 수 있으면 더 이상 검사 할 필요가 없습니다.


좋은 생각처럼 들리지만 1 단계에서 이동하기 전에 충돌 감지를 수행하여 이동할 수 없는지 확인해야합니까?
Sycren

시뮬레이션을 계속하지 않으면 충돌을 일으킨 후 그 이동과 반대 방향으로 충돌이 발생했는지 확인할 수 있습니다.
Ali1S232

고맙습니다. 쿼드 트리 외에도 워크로드를 분할하는 다른 방법을 생각할 수 있습니까?
Sycren

내 세그먼테이션이 완전히 쿼드 트리 자체가 아니라 정확도를 높이기 위해 하나 이상의 추가 그룹이 있으므로 쿼드 트리 스타일이 훨씬 더 쉽게 처리 할 수 ​​있습니다. 세계 크기에 따라 더 많은 그룹을 추가 할 수 있으며 이는 각주기에서 더 적은 검사를 의미합니다. 메모리 소비와 컴퓨팅 속도 사이의 균형입니다. 각 그룹마다 반드시 하나의 스레드 일 필요는 없습니다. 여러 그룹을 계산하기 위해 스레드를 가질 수 있습니다. 두 개 이상의 스레드간에 그룹 계산을 분할 할 수도 있습니다.
Ali1S232

@Gajet 사진을 올바르게 이해하면 그룹의 겹치는 영역이 매우 크기 때문에 이중 계산이 많이 발생합니다. 이 질문에 수백만 점까지 시뮬레이션하도록 요청하면 엄청난 낭비가 될 것입니다.
Maik Semder

2

최근에 이러한 답변 중 일부를 출발점으로 사용 하여이 문제를 해결했습니다. 가장 도움이되는 것은 보이드가 일종의 간단한 n- 바디 시뮬레이션이라는 것입니다. 각 보이드는 이웃에 힘을 가하는 입자입니다.

Linde 논문을 읽기가 어렵다는 것을 알았습니다. 대신 SJ Plimpton의 "단거리 분자 역학을위한 빠른 병렬 알고리즘"을 살펴 보는 것이 좋습니다. Linde가 언급 한 . Plimpton의 논문은 더 나은 수치로 훨씬 더 읽기 쉽고 상세합니다.

요컨대, 원자 분해 방법은 원자의 하위 집합을 각 프로세서에 영구적으로 할당하고, 힘 분해 방법은 쌍 단위 힘 계산의 하위 집합을 각 proc에 할당하고 공간 분해 방법은 시뮬레이션 상자의 하위 영역을 각 proc에 할당합니다. .

AD를 사용해 보는 것이 좋습니다. 이해하고 구현하는 것이 가장 쉽습니다. FD는 매우 유사합니다. 여기 당신에게 기와 및 감소를 크게 일련의 성능을 능가 할 수있는 방법의 거친 아이디어를 줄 것이다 FD를 사용하여 CUDA와 NVIDIA의 N 바디 시뮬레이션이다.

SD 구현은 일반적으로 최적화 기술이며 구현하려면 어느 정도의 안무가 필요합니다. 거의 항상 빠르며 확장 성이 좋습니다.

AD / FD는 각 보이드마다 "이웃 목록"을 작성해야하기 때문입니다. 모든 boid 필요가 이웃의 위치를 알고 있다면, 그들 사이의 통신은 O입니다 ( N ²). Verlet 네이버 목록을 사용하여 각 보이드가 확인하는 영역의 크기를 줄일 수 있습니다. 이렇게하면 모든 단계 대신 몇 단계마다 목록을 다시 작성할 수 있지만 여전히 O ( n ²)입니다. SD에서, 각 셀은 이웃리스트를 유지하는 반면, AD / FD에서 모든 보이드는 이웃리스트를 갖는다. 따라서 모든 보이드가 서로 통신하는 대신 모든 셀이 서로 통신합니다. 의사 소통의 감소는 속도 증가의 시작입니다.

불행하게도 boids 문제는 SD를 약간 방해합니다. 각 프로세서가 셀을 추적하도록하는 것이 보이드가 전체 영역에 걸쳐 고르게 분포 될 때 가장 유리합니다. 그러나 당신 보이드가 함께 모여 있기원합니다 ! 무리가 제대로 작동하면 대부분의 프로세서가 빈 목록을 서로 교환하면서 똑딱 거리며 작은 셀 그룹이 AD 또는 FD와 동일한 계산을 수행하게됩니다.

이를 처리하기 위해 주어진 시간에 빈 셀 수를 최소화하기 위해 셀 크기 (상수)를 수학적으로 조정하거나 쿼드 트리에 Barnes-Hut 알고리즘을 사용할 수 있습니다. BH 알고리즘은 매우 강력합니다. 역설적으로 병렬 아키텍처에서는 구현하기가 매우 어렵습니다. 이는 BH 트리가 불규칙하기 때문에 병렬 스레드가 엄청나게 다양한 속도로 스레드를 가로 질러 스레드 분기를 발생시킵니다. Salmon과 Dubinski는 프로세서간에 쿼드 트리를 균등하게 분배하기 위해 직교 재귀 이분법 알고리즘을 제시했으며, 대부분의 병렬 아키텍처에 대해 반복적으로 복원해야합니다.

보시다시피, 우리는 현재 최적화와 흑 마법의 영역에 있습니다. 다시 Plimpton의 논문을 읽어보고 의미가 있는지 확인하십시오.


1

나는 당신이 토 로이드 시스템이라고 가정하고, 각 유닛이 하위 영역을 갖도록 공간으로 분할 할 수 있습니다.

각 단계에서 입자가 이동하고, 하위 영역으로 나가는 입자는 관련 프로세서로 전송됩니다. 통신 단계는 프로세서를 동기화하고 이물질 입자 위치 (있는 경우)를 정교하게하기 위해 마지막 단계가 수행됩니다.

여기에 세 가지 문제가 있습니다.

  • 1) 하위 영역의 모양 :

직사각형을 선택할 수는 있지만 cirlces에 비해 면적 / 둘레 비율이 작습니다. 경계가 클수록 더 많은 입자가 남을 것입니다. Cicle은 최고의 A / p 비율을 나타내지 만 테셀레이션에는 사용할 수 없으므로 평균 A / p 비율이 좋은 일부 (일반적으로 반 정기적) 테셀레이션을 처리해야합니다. 분명히 셀 좌표로 술 인덱스를 계산하는 것은 간단해야하므로 매우 이국적인 태슬을 시도하기 전에 이것을 고려하십시오.

  • 2) 통신 프로토콜 :

사용중인 통신 인프라 종류에 따라 프로세서 간 경계 정보를 분산시키는 방법을 생각할 수 있습니다. 브로드 캐스팅 대 피어 투 피어 재구성 대 피어 투 피어 통신은 모두 옵션입니다.

  • 3) 하위 영역 할당 :

각 단계마다 동기화가 있기 때문에 정교함의 균형을 유지해야합니다. 영역을 프로세서에 정적으로 또는 동적으로 할당하도록 선택할 수 있습니다. 만약 당신의 공간이 활성 파티클로 덮여 있지 않다면 큰 문제는 아니지만 충돌이 파티클을 비활성화 할 때이 경우에는 사실이 아닐 수 있다고 믿습니다. 모든 프로세서가 국경 간 정보를 공유하는 경우 일부 단축키를 사용할 수 있지만 고려해야 할 사항이 있습니다.


@Fxlll 나는 도넛 형 시스템이 아닌 도넛 형 시스템이 무엇을 의미하는지 잘 모르겠습니다. 입자가 오른쪽에서 떨어지면 왼쪽에 다시 나타 납니까? 그렇지 않은 경우 입자가 오른쪽에 닿으면 다른 방향으로 움직입니다.
Sycren

@Sycren ok이 경우에는 tasselation과 엣지의 영역을 특별한 방식으로 처리하는 것에 대해 몇 가지 고려해야합니다
FxIII

-1

단서에 대한 시뮬레이션을 시도하십시오 https://github.com/wahabjawed/Boids-Simulation

나는 이것을 XNA에서 개발했다


완전한 프로젝트에 연결하는 것만으로는 좋은 대답이 아닙니다. 독자는 질문과 관련된 부분을 찾은 후에도 문제를 해결하는 방법을 이해해야 할 때까지 소스를 파헤쳐 야합니다. 문제에 접근 한 방법과 다른 답변에 설명 된 솔루션보다 어떤 이점이 있는지 일반 영어로 설명해 주시겠습니까? 설명을 이해하는 데 도움이되는 경우 짧은 코드 스 니펫을 복사하여 붙여 넣을 수 있습니다.
Philipp
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.