Этот вопрос о лучшей стратегии для реализации следующего моделирования в C ++.
Я пытаюсь сделать моделирование как часть исследовательского проекта по физике, который в основном отслеживает динамику цепочкиузлы в пространстве.Каждый узел содержит позицию вместе с определенными параметрами (локальная кривизна, скорость, расстояние до соседей и т. Д.), Которые все эволюционируют через время.
Каждый шаг по времени может быть разбит на эти четыре части:
- Рассчитать локальные параметры.Значения зависят от ближайших соседей в цепочке.
- Рассчитать глобальные параметры.
- Развитие.Положение каждого узла перемещается на небольшую величину, в зависимости от глобальных и локальных параметров и некоторых случайных силовых полей.
- Заполнение.Новые узлы вставляются, если расстояние между двумя последовательными узлами достигает критического значения.
(Кроме того, узлы могут застрять, что делает их неактивными до конца симуляции. Локальные параметры неактивных узлов с неактивными соседями не изменятся и не требуют дополнительных вычислений..)
Каждый узел содержит ~ 60 байтов, у меня ~ 100 000 узлов в цепочке, и мне нужно развить цепочку приблизительно за ~ 1 000 000 временных шагов.Однако я хотел бы максимизировать эти числа, так как это повысило бы точность моего моделирования, но с ограничением, что моделирование выполняется в разумные сроки (~ часы).(~ 30% узлов будут неактивны.)
Я начал реализовывать это моделирование в виде двусвязного списка в C ++.Это кажется естественным, поскольку мне нужно вставить новые узлы между существующими и потому, что локальные параметры зависят от ближайших соседей.(Я добавил дополнительный указатель на следующий активный узел, чтобы избежать ненужных вычислений всякий раз, когда я зацикливаюсь по всей цепочке).
Я не эксперт, когда дело доходит до распараллеливания (или кодирования в этом отношении),но я играл с OpenMP, и мне действительно нравится, как я могу ускорить цикл независимых операций с двумя строками кода.Я не знаю, как заставить мой связанный список делать что-то параллельно, или он вообще работает (?).Так что у меня появилась идея работать с вектором stl.Где вместо того, чтобы иметь указатели на ближайших соседей, я мог хранить индексы соседей и получать к ним доступ с помощью стандартного поиска.Я также мог бы отсортировать вектор по позиции цепочки (каждый x-й шаг), чтобы получить лучшую локальность в памяти.Этот подход позволил бы зацикливаться на OpenMP.
Я несколько испуган этой идеей, поскольку мне не приходится иметь дело с управлением памятью.И я предполагаю, что реализация вектора stl намного лучше, чем мой простой способ «нового» и «удаления» для работы с узлами в списке.Я знаю, что мог бы сделать то же самое со списками stl, но мне не нравится способ доступа к ближайшим соседям с помощью итераторов.
Поэтому я спрашиваю вас, 1337 h4x0r и опытных программистов, что будетлучший дизайн для моей симуляции?Описан ли векторный подход выше хорошей идеи?Или есть какие-то хитрости для воспроизведения в связанном списке, чтобы заставить их работать с OpenMP?Или я должен рассмотреть совершенно другой подход?
Симуляция будет выполняться на компьютере с 8 ядрами и 48 ГБ ОЗУ, поэтому я предполагаю, что могу обменять много памяти на скорость.
Заранее спасибо
Редактировать: Мне нужно добавлять 1-2% новых узлов каждый раз, так что их сохранение в виде вектора без индексов для ближайших соседей не будет работать, если я не отсортируювектор каждый шаг по времени.