Я переписываю код, который я разработал на python, в c ++, в основном для повышения скорости; в то же время надеясь получить больше опыта в этом языке. Я также планирую использовать openMP для распараллеливания этого кода на 48 ядрах, которые совместно используют 204 ГБ памяти.
Программа, которую я пишу, проста, я импортирую файл hdf5, который является 3D:
A [T] [X] [E], где T связан с каждым временным шагом моделирования, X представляет место измерения поля, а E (0: 2) представляет электрическое поле в x, y, z.
Каждый элемент в A является двойным, и размеры ячеек охватывают: A [15000] [80] [3].
Первый сбой, с которым я столкнулся, — это ввод этого «большого» файла h5 в массив, и мне хотелось бы получить профессиональное мнение, прежде чем я продолжу. Моя первая попытка:
...
#define RANK 3
#define DIM1 15001
#define DIM2 80
#define DIM3 3
using namespace std;
int main (void)
{
// Define HDF5 variables for opening file.
hid_t file1, dataset1;
double bufnew[DIM1][DIM2][DIM3];
herr_t ret;
uint i, j, k;
file1 = H5Fopen (FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
dataset1 = H5Dopen (file1, "EFieldOnLine", H5P_DEFAULT);
ret = H5Dread (dataset1, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
H5P_DEFAULT, bufnew);
cout << "Let's try dumping 0->100 elements" << endl;
for(i=1; i < 100; i++) cout << bufnew[i][20][2] << endl;
...
что приводит к ошибке сегментации из объявления массива. Моим следующим шагом было использование либо трехмерного массива (нового), либо трехмерного вектора. Тем не менее, я видел много споров против этих методов, и что более важно, мне нужен только ОДИН компонент E, т.е. я хотел бы изменить A [T] [X] [E] -> B [T] [X] для скажем, х-компонента Е.
Извините за длинный пост, но я хотел быть как можно более ясным и хотел бы еще раз подчеркнуть, что мне интересно узнать, как писать самый быстрый и эффективный код.
Я ценю все ваши предложения, время и мудрость.
Определение массива как локальной переменной означает его размещение в стеке. Размер стека обычно ограничен несколькими мегабайтами, и переполнение стека, безусловно, приводит к segfault. Большие структуры данных должны динамически размещаться в куче (используя new
оператор) или статически (когда определены как глобальные переменные).
Я бы не советовал составлять вектор векторов для таких размерностей.
Вместо этого создаем одномерный массив для хранения всех значений
double *bufnew = new double[DIM1*DIM2*DIM3];
и доступ к нему по следующей формуле для расчета линейного положения данного трехмерного элемента
bufnew[(T*DIM2+X)*DIM3+E] = ... ; // bufnew[T][X][E]
должно работать нормально.
Других решений пока нет …