Недавно я решил эту проблему, используя некоторые из этих ответов в качестве отправной точки. Самое полезное, что нужно иметь в виду, это то, что boids - это своего рода простая симуляция n-тела: каждый boid - это частица, которая воздействует на соседей.
Мне было трудно читать бумагу Линде; Вместо этого я предлагаю взглянуть на «Быстрые параллельные алгоритмы короткой молекулярной динамики» С. Дж. Плимптона , на которые ссылается Линде. Бумага Плимптона гораздо более читабельна и детальна с лучшими цифрами:
В двух словах, методы атомного разложения постоянно назначают подмножество атомов каждому процессору, методы силового разложения назначают подмножество парных вычислений силы для каждого процесса, а методы пространственного разложения назначают подрегион блока моделирования каждому процессу. ,
Я рекомендую вам попробовать AD. Это проще всего понять и реализовать. ФД очень похож. Вот симуляция n-тела nVidia с использованием CUDA с использованием FD, которая должна дать вам общее представление о том, как мозаичное построение и сокращение могут помочь значительно превзойти производительность последовательного интерфейса.
Реализации SD, как правило, оптимизируют методы и требуют определенной степени хореографии для реализации. Они почти всегда быстрее и лучше масштабируются.
Это потому, что AD / FD требует построения «списка соседей» для каждого boid. Если каждому бойду необходимо знать положение своих соседей, связь между ними будет O ( n ²). Вы можете использовать списки соседей Verlet, чтобы уменьшить размер области, которую проверяет каждый boid, что позволяет вам перестраивать список каждые несколько шагов вместо каждого шага, но это все равно O ( n ²). В SD каждая ячейка содержит список соседей, тогда как в AD / FD у каждого boid есть список соседей. Таким образом, вместо того, чтобы каждый бид общался друг с другом, каждая клетка общалась друг с другом. Это сокращение в общении, откуда происходит увеличение скорости.
К сожалению, проблема Boids немного саботирует SD. Отслеживание ячейки каждым процессором является наиболее выгодным, когда боиды несколько равномерно распределены по всему региону. Но вы хотите, чтобы boids собирались вместе! Если ваша стая ведет себя должным образом, подавляющее большинство ваших процессоров будут отсчитывать время, обмениваясь пустыми списками, и небольшая группа ячеек в итоге выполнит те же вычисления, что и AD или FD.
Чтобы справиться с этим, вы можете либо математически настроить размер ячеек (который является постоянным), чтобы минимизировать количество пустых ячеек в любой момент времени, либо использовать алгоритм Барнса-Хата для четырех деревьев. Алгоритм ЧД невероятно мощный. Как это ни парадоксально, это очень сложно реализовать на параллельных архитектурах. Это связано с тем, что дерево BH нерегулярно, поэтому параллельные потоки будут проходить по нему с сильно изменяющимися скоростями, что приведет к расхождению потоков. Salmon и Dubinski представили ортогональные рекурсивные алгоритмы деления пополам для равномерного распределения квадродеревьев между процессорами, которые должны быть повторены итеративно для большинства параллельных архитектур.
Как видите, на данный момент мы явно находимся в области оптимизации и черной магии. Опять же, попробуйте прочитать статью Плимптона и посмотрите, имеет ли это смысл.