Ostatnio rozwiązałem ten problem, wykorzystując niektóre z tych odpowiedzi jako punkt wyjścia. Najbardziej pomocną rzeczą, o której należy pamiętać, jest to, że boidy są rodzajem prostej symulacji n-ciała: każda boid jest cząsteczką, która wywiera siłę na sąsiadów.
Trudno mi było przeczytać artykuł Linde; Zamiast tego sugeruję spojrzenie na „Szybkie równoległe algorytmy SJ Plimpton dla dynamiki molekularnej bliskiego zasięgu” , do których nawiązał Linde. Artykuł Plimpton jest o wiele bardziej czytelny i szczegółowy z lepszymi danymi:
W skrócie, metody dekompozycji atomów przypisują na stałe podzbiór atomów do każdego procesora, metody dekompozycji sił przypisują podzbiór par obliczeń siły do każdego proc, a metody dekompozycji przestrzennej przypisują podregion pola symulacji do każdego proc .
Polecam spróbować AD. Jest najłatwiejszy do zrozumienia i wdrożenia. FD jest bardzo podobny. Oto symulacja n-ciała nVidii z CUDA przy użyciu FD, która powinna dać ogólny obraz tego, w jaki sposób kafelkowanie i redukcja mogą znacznie przewyższyć wydajność szeregową.
Implementacje SD są ogólnie technikami optymalizacji i wymagają pewnego stopnia choreografii do wdrożenia. Są prawie zawsze szybsze i lepiej skalowalne.
Wynika to z faktu, że AD / FD wymaga zbudowania „listy sąsiadów” dla każdego boid. Jeśli każdy boid musi znać pozycję swoich sąsiadów, komunikacja między nimi to O ( n ²). Możesz użyć list sąsiadów Verlet, aby zmniejszyć rozmiar obszaru, który sprawdza każdy boid, co pozwala przebudowywać listę co kilka kroków czasowych zamiast każdego kroku, ale nadal jest to O ( n ²). W SD każda komórka utrzymuje listę sąsiadów, podczas gdy w AD / FD każdy boid ma listę sąsiadów. Więc zamiast każdego boidu komunikującego się ze sobą, każda komórka komunikuje się ze sobą. To zmniejszenie komunikacji jest przyczyną wzrostu prędkości.
Niestety problem boidów nieznacznie sabotuje SD. Śledzenie komórki przez każdy procesor jest najbardziej korzystne, gdy boidy są nieco równomiernie rozmieszczone w całym regionie. Ale chcesz, aby klastry łączyły się razem! Jeśli twoje stado zachowuje się prawidłowo, znaczna większość twoich procesorów będzie tykała, wymieniając między sobą puste listy, a mała grupa komórek zakończy te same obliczenia, które wykonałyby AD lub FD.
Aby sobie z tym poradzić, możesz albo matematycznie dostroić rozmiar komórek (który jest stały), aby zminimalizować liczbę pustych komórek w danym momencie, lub użyć algorytmu Barnes-Hut dla quadów. Algorytm BH jest niezwykle potężny. Paradoksalnie niezwykle trudne jest wdrożenie na architekturach równoległych. Wynika to z faktu, że drzewo BH jest nieregularne, więc równoległe wątki będą je przechodzić z bardzo różnymi prędkościami, powodując rozbieżność nici. Salmon i Dubiński przedstawili ortogonalne rekurencyjne algorytmy bisekcji, aby równomiernie rozdzielić kwadraty między procesory, które muszą być powtórzone iteracyjnie dla większości równoległych architektur.
Jak widać, w tym momencie jesteśmy wyraźnie w dziedzinie optymalizacji i czarnej magii. Ponownie spróbuj przeczytać artykuł Plimptona i sprawdź, czy ma to jakiś sens.