使用HDF5 H5Dread过多的内存

时间:2013-08-27 13:21:56

标签: c++ memory-management hdf5

由于使用了太多内存,导致程序崩溃。这是HDF5 1.8.9。

大多数情况下,我们没有问题,但有时文件较大,会发生以下情况:

在这个例子中,我有一个 325MB HDF5文件,这会导致 2GB 的内存用于读取它的一些值('timeteps'的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 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。就我而言,这是因为数据集的维度无限(正如Yossarian所说)。

为了验证错误,我创建了两个版本的数据集:一个版本具有无限的尺寸长度,另一个版本具有固定的尺寸长度。两个数据集都具有相同的数据。内存消耗加上无限制,而使用常量长度创建的数据集没有任何问题。

还有一件事需要提及:我的原始数据集是由较旧版本的NetCDF创建的,我使用“nccopy -k 4”将其转换为NetCDF4 / HDF5格式。

答案 1 :(得分:1)

Yossarian的评论包含了线索 - 当我们检查主数据集的分块时,内存爆炸实际上来自一个仅包含时间值的关联1D数据集。后一个数据集的块大小为1.增加块大小解决了问题。