4

我们有程序由于使用过多的内存而崩溃。这是 HDF5 1.8.9。

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

在这个例子中,我有一个325MB 的 HDF5 文件,这会导致使用2GB的内存来读取它的一些值(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";
}

)

4

2 回答 2

1

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

为了验证错误,我创建了两个版本的数据集:一个具有无限维度长度,另一个具有固定维度长度。两个数据集具有相同的数据。内存消耗随着无限制而飙升,而以恒定长度创建的数据集没有任何问题。

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

于 2013-09-15T23:33:29.257 回答
1

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

于 2013-10-24T14:54:46.940 回答