Чрезмерное использование памяти с HDF5 H5Dread


У нас были сбои программ из-за использования слишком большого объема памяти. Это с HDF5 1.8.9.

В большинстве случаев у нас нет проблем, но иногда с большими файлами происходит следующее:

В этом примере у меня есть 325MB HDF5-файл , который заставляет 2GB памяти использоваться для чтения некоторых его значений ("timesteps" точек данных в файле HDF5, всего 400,001 значения двойной точности). Похоже, что наше использование метода H5Dread является причина проблемы. Есть идеи, что мы здесь делаем не так?

Метод, вызывающий проблему, выглядит следующим образом:

std::vector<double> Hdf5DataReader::GetUnlimitedDimensionValues() 
{ 
    // Define hyperslab in the dataset 
    hid_t time_dataspace = H5Dget_space(mUnlimitedDatasetId); 

    // Get the dataset/dataspace dimensions
    hsize_t num_timesteps;
    H5Sget_simple_extent_dims(time_dataspace, &num_timesteps, NULL);

    // Data buffer to return 
    std::cout << "Number of timesteps we are reserving memory for = " << num_timesteps << "n"; 
    std::vector<double> ret(num_timesteps);         

    PrintMemoryUsage("made memory space"); 

    // Read data from hyperslab in the file into the hyperslab in memory 
    H5Dread(mUnlimitedDatasetId, 
            H5T_NATIVE_DOUBLE, 
            H5S_ALL, 
            H5S_ALL, 
            H5P_DEFAULT, 
            &ret[0]); 

    PrintMemoryUsage("read into memory space"); 

    H5Sclose(time_dataspace); 

    return ret; 
} 

А выход -

Number of timesteps we are reserving memory for = 400001
made memory space: memory use = 43.5898 MB.
read into memory space: memory use = 2182.4 MB.

(Использование этого кода для диагностики объема памяти, выделенной программе-выглядит ли это разумно?:

#include <unistd.h>
#include <sys/resource.h>

void PrintMemoryUsage(const std::string& rPrefix)
{
    struct rusage rusage;
    getrusage( RUSAGE_SELF, &rusage );

    double max_res = (double)(rusage.ru_maxrss)/(1024);// Convert KB to MB
    std::cout << rPrefix << ": memory use = " << max_res <<  " MB.n";
}

)

2 4

2 ответа:

Комментарий Йоссариана содержал подсказку - в то время как мы проверили фрагментацию для основного набора данных, взрыв памяти на самом деле произошел из связанного набора данных 1D, содержащего только значения времени. Последний набор данных имел размер блока 1. Увеличение размера куска решило проблему.

Я столкнулся с той же проблемой. В моем случае это было связано с неограниченной размерностью набора данных (как упоминал Йоссариан).

Чтобы проверить ошибку, я создал две версии своего набора данных: одну с неограниченной длиной измерения, а другую с фиксированной длиной измерения. Оба набора данных содержали одинаковые данные. Потребление памяти резко возросло с неограниченным, в то время как набор данных, созданный с постоянной длиной, не имел никаких проблем.

Еще одна вещь, чтобы Примечание: мой исходный набор данных был создан более старой версией NetCDF, и я преобразовал его в формат NetCDF4/HDF5 с помощью "nccopy-k 4".