Двойной массив с одним элементом и двойная переменная (C++)C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Двойной массив с одним элементом и двойная переменная (C++)

Сообщение Anonymous »

Я работаю над кодом C++ для моделирования N взаимодействующих частиц (как в физических частицах). Частицы движутся в d измерениях (d=1,2 или 3). На каждой итерации алгоритма силы вычисляются на основе всех расстояний между парами частиц (самая затратная часть с точки зрения времени выполнения). Эффективность является ключевым моментом в этих симуляциях. В моей текущей настройке у меня есть три разные версии кода, в зависимости от пространственного измерения d системы. Положение частицы, скорости и силы хранятся в структуре типа

Код: Выделить всё

struct coordinate{
double x, double y, double z   // 3 coordinates for the 3-dimensional case.
}
Теперь я хотел объединить эти три версии кода, чтобы иметь возможность вводить измерение в начале моделирования через argv. Очевидно, что размерность и количество значений типа double в структуре неизвестны во время компиляции. Вопрос в том, как написать новую версию кода без потери эффективности.
Сначала я по наивности удалил всю структуру и заменил ее на std::vector, размер которого будет определяться размером d. Однако при тестировании кода доступ к векторным элементам в узких циклах моей симуляции и определение новых векторов оказались намного дороже, чем простая работа со структурами, что меня удивило. По-видимому, это связано с тем, что std::vector распределяет память динамически, в отличие от структур. Более того, если у меня есть двумерный вектор std::vector , где количество строк соответствует количеству частиц, а столбцов - координатам (x,y,z) ( в 3D), кажется, что внутренние векторы не хранятся в памяти рядом друг с другом (в отличие от версии структуры std::vector со структурой выше, где все (x,y, з) всего частицы хранятся последовательно).
Следующая идея заключалась в том, чтобы вместо этого работать с std::array, где я всегда определял массив некоторого максимально допустимого размера MAXDIM > (известно во время компиляции), а затем работать только с элементами массива, заданными размером d, введенным во время выполнения. Для этого я создал новую версию структуры координат:

Код: Выделить всё

constexpr size_t MAXDIM = 3; // Maximum allowed dimension.

class coordinate {

public:

// Default constructor.
coordinate()
: dimension {0} {
coords.fill(0.0); // Initialize all elements to 0.0.
}

coordinate(size_t dim)
{
set_dimension(dim);
coords.fill(0.0);
}

// Method to set the runtime dimension.
void set_dimension(size_t dim) {
if (dim > MAXDIM) {
throw std::out_of_range("Dimension exceeds MAXDIM.");
}
dimension = dim;
}

// Access operator for reading/writing within the runtime dimension.
double& operator[](size_t index) {
return coords[index];
}

const double& operator[](size_t index) const {
return coords[index];
}

private:
std::array coords; // Fixed-size array.
size_t dimension;                  // Actual dimension.

};

Если я использую эту версию кода и активирую все оптимизации компилятора (для G ++, это флаг -O3 ), полученная версия кода точно так же быстро, как и исходный код При использовании 2 измерений, что великолепно. Однако, что меня удивило, так это то, что при использовании только 1 измерения код все еще на 20-30% медленнее, чем оригинальная версия. Координаты хранились в виде простых двойных переменных, в 1D-вазе компилятор понимал бы, что структура содержит только один скалярный объект, для которого он может выполнять определенные оптимизации, которые не может работать, если этот скаляр хранится в массиве. Однако в случае 2D рабочая нагрузка для массива, в котором хранится два числа или хранение двух чисел в виде отдельных двойных значений, идентична, потому что эти скалярные оптимизации не играют там роли. < /P>
Если бы кто-то работал только с 1D-вазом, я, очевидно, не хранит единую координату в массиве, но я хочу, чтобы мой код работал во всех измерениях без перекомпилирования (поскольку я хочу превратить его в приложение).
Не видя больше кодовой базы, есть ли у кого -нибудь представление о том, правильный ли Chatgpt и как решить эту проблему? Я уже профилировал обе версии кода Perf , но не смог найти примечательные различия (я могу опубликовать результаты PERF, если это необходимо).


Подробнее здесь: https://stackoverflow.com/questions/793 ... variable-c
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»