J'ai abordé ce problème récemment en utilisant certaines de ces réponses comme point de départ. La chose la plus utile à garder à l'esprit est que les boids sont une sorte de simulation simple à n corps: chaque boid est une particule qui exerce une force sur ses voisins.
J'ai trouvé le journal Linde difficile à lire; Je suggère plutôt de regarder les "algorithmes parallèles rapides pour la dynamique moléculaire à courte portée" de SJ Plimpton. , auxquels Linde a fait référence. L'article de Plimpton est beaucoup plus lisible et détaillé avec de meilleurs chiffres:
En résumé, les méthodes de décomposition des atomes attribuent un sous-ensemble d'atomes de façon permanente à chaque processeur, les méthodes de décomposition en force attribuent un sous-ensemble de calculs de force par paire à chaque proc, et les méthodes de décomposition spatiale affectent une sous-région de la boîte de simulation à chaque proc .
Je vous recommande d'essayer AD. C'est le plus simple à comprendre et à mettre en œuvre. FD est très similaire. Voici la simulation à n corps de nVidia avec CUDA à l'aide de FD, qui devrait vous donner une idée approximative de la façon dont la mosaïque et la réduction peuvent aider à dépasser considérablement les performances série.
Les implémentations SD sont généralement des techniques d'optimisation et nécessitent un certain degré de chorégraphie à implémenter. Ils sont presque toujours plus rapides et évoluent mieux.
En effet, AD / FD nécessite la construction d'une "liste de voisins" pour chaque boid. Si chaque boid a besoin de connaître la position de ses voisins, la communication entre eux est O ( n ²). Vous pouvez utiliser des listes de voisins Verlet pour réduire la taille de la zone vérifie chaque Boid, qui vous permet de reconstruire la liste tous les deux au lieu de chaque pas de temps pas, mais il est encore O ( n ²). En SD, chaque cellule conserve une liste de voisins, alors qu'en AD / FD chaque boid a une liste de voisins. Ainsi, au lieu que chaque boid communique entre eux, chaque cellule communique entre elles. Cette réduction de la communication est à l'origine de l'augmentation de la vitesse.
Malheureusement, le problème des boids sabote légèrement SD. Le fait que chaque processeur garde la trace d'une cellule est plus avantageux lorsque les boids sont répartis de manière quelque peu uniforme sur toute la région. Mais vous voulez que les boids se regroupent! Si votre troupeau se comporte correctement, la grande majorité de vos processeurs s'éloigneront, échangeant des listes vides entre eux, et un petit groupe de cellules finira par effectuer les mêmes calculs qu'AD ou FD.
Pour y faire face, vous pouvez soit ajuster mathématiquement la taille des cellules (qui est constante) pour minimiser le nombre de cellules vides à un moment donné, soit utiliser l'algorithme Barnes-Hut pour les quadruples arbres. L'algorithme BH est incroyablement puissant. Paradoxalement, il est extrêmement difficile à mettre en œuvre sur des architectures parallèles. En effet, un arbre BH est irrégulier, donc les threads parallèles le traversent à des vitesses très variables, ce qui entraîne une divergence de thread. Salmon et Dubinski ont présenté des algorithmes de bissection récursive orthogonaux pour répartir équitablement les quadruples entre les processeurs, qui doivent être retraités de manière itérative pour la plupart des architectures parallèles.
Comme vous pouvez le voir, nous sommes clairement dans le domaine de l'optimisation et de la magie noire à ce stade. Encore une fois, essayez de lire l'article de Plimpton et voyez si cela a un sens.