HDF5复合型原生与IEEE
HDF5 Compound type Native vs. IEEE
我只是拿起HDF5,我有点困惑为内存创建数据和为文件创建数据之间的差异。有什么区别?
在本例中,创建复合类型data需要在内存中创建数据并将其放在文件中:
/*
* Create the memory data type.
*/
s1_tid = H5Tcreate (H5T_COMPOUND, sizeof(s1_t));
H5Tinsert(s1_tid, "a_name", HOFFSET(s1_t, a), H5T_NATIVE_INT);
H5Tinsert(s1_tid, "c_name", HOFFSET(s1_t, c), H5T_NATIVE_DOUBLE);
H5Tinsert(s1_tid, "b_name", HOFFSET(s1_t, b), H5T_NATIVE_FLOAT);
/*
* Create the dataset.
*/
dataset = H5Dcreate(file, DATASETNAME, s1_tid, space, H5P_DEFAULT);
/*
* Wtite data to the dataset;
*/
status = H5Dwrite(dataset, s1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s1);
然而,在这里的另一个示例中,作者还为文件创建了一个复合数据,它指定了不同的数据类型。例如,在为内存创建数据类型时,serial_no使用类型H5T_NATIVE_INT,但是在为文件创建数据类型时,serial_no使用H5T_STD_I64BE。他为什么要这么做?
/*
* Create the compound datatype for memory.
*/
memtype = H5Tcreate (H5T_COMPOUND, sizeof (sensor_t));
status = H5Tinsert (memtype, "Serial number",
HOFFSET (sensor_t, serial_no), H5T_NATIVE_INT);
status = H5Tinsert (memtype, "Location", HOFFSET (sensor_t, location),
strtype);
status = H5Tinsert (memtype, "Temperature (F)",
HOFFSET (sensor_t, temperature), H5T_NATIVE_DOUBLE);
status = H5Tinsert (memtype, "Pressure (inHg)",
HOFFSET (sensor_t, pressure), H5T_NATIVE_DOUBLE);
/*
* Create the compound datatype for the file. Because the standard
* types we are using for the file may have different sizes than
* the corresponding native types, we must manually calculate the
* offset of each member.
*/
filetype = H5Tcreate (H5T_COMPOUND, 8 + sizeof (hvl_t) + 8 + 8);
status = H5Tinsert (filetype, "Serial number", 0, H5T_STD_I64BE);
status = H5Tinsert (filetype, "Location", 8, strtype);
status = H5Tinsert (filetype, "Temperature (F)", 8 + sizeof (hvl_t),
H5T_IEEE_F64BE);
status = H5Tinsert (filetype, "Pressure (inHg)", 8 + sizeof (hvl_t) + 8,
H5T_IEEE_F64BE);
/*
* Create dataspace. Setting maximum size to NULL sets the maximum
* size to be the current size.
*/
space = H5Screate_simple (1, dims, NULL);
/*
* Create the dataset and write the compound data to it.
*/
dset = H5Dcreate (file, DATASET, filetype, space, H5P_DEFAULT, H5P_DEFAULT,
H5P_DEFAULT);
status = H5Dwrite (dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);
这两种方法的区别是什么?
From http://www.hdfgroup.org/HDF5/doc/UG/UG_frame11Datatypes.html:
H5T_NATIVE_INT对应于C int类型。在基于英特尔的PC上,此类型与H5T_STD_I32LE相同,而在MIPS系统上,这将等同于H5T_STD_I32BE。
也就是说,H5T_NATIVE_INT在不同类型的处理器上具有不同的内存布局。如果您的数据只在内存中使用,这意味着您的数据不会流出这台机器,您可能喜欢使用H5T_NATIVE_INT来获得更好的性能。
但是如果你的数据将被保存到文件中,并且将被不同的系统使用,你必须指定一个特定的int类型来保持你的数据可以被正确读取,例如H5T_STD_I64BE或H5T_STD_I32LE。如果您使用H5T_NATIVE_INT,并且您在基于Intel的PC上创建了一个数据文件,则该数字将保存为H5T_STD_I32LE。当这个文件被MIPS系统使用时,它将把这个数字读为H5T_STD_I32BE,这是不期望的。
这里的另一个答案是缺少一些关键的想法,使使用HDF5数据类型看起来比它更难。
首先,NATIVE类型只是C类型在该平台上映射到的别名(这是在构建HDF5库时检测到的)。如果在代码中使用它们并查看用h5dump工具创建的文件,则不会看到NATIVE数据类型,而是会看到真正的数据类型(H5T_STD_I32LE或诸如此类的东西)。诚然,这些NATIVE类型有点令人困惑,但它们对于C类型和HDF5数据类型之间的映射很方便,而不必知道您所在系统的字节顺序。
我想澄清的另一个误解是,库会在合理的情况下为您转换类型。如果数据集包含H5T_STD_I32BE值,并且您在小端系统上声明I/O缓冲区为H5T_NATIVE_INT,那么HDF5库将为您将大端数据集整数转换为内存中的小端整数。您不需要自己执行字节交换。
这是一种简单的思考方式:
- 在调用H5Dcreate()时声明数据集的存储数据类型。
- 你声明的I/O缓冲区的数据类型当你调用H5Dread()和H5Dwrite()。
同样,如果这些不同且类型转换是合理的,则将在读/写调用期间转换数据。
注意,在时间关键型应用程序中,这种类型转换可能会影响性能。如果写入和读取数据的平台在字节顺序或字长方面不同,您可能希望显式设置数据类型,而不是使用NATIVE别名,以便您可以强制转换在不太重要的平台上进行。
示例:假设您有一个BE写入器和LE读取器,数据到达很慢,但读取必须尽可能快。在这种情况下,您需要显式地创建数据集来存储H5T_STD_I32LE数据,以便在写入器上进行数据类型转换。
最后一件事——在构造复合类型时,最好使用HOFFSET(s,m)宏,而不是手动计算偏移量。它更容易维护,你的代码会看起来更好。
如果你想了解更多关于HDF5数据类型的信息,请查看用户指南的第6章:https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html
你也可以在参考手册中查看H5T API文档:https://support.hdfgroup.org/HDF5/doc/RM/RM_H5Front.html
- Android Studio 中带有静态库的原生C++代码
- 如何在 Android Studio 4 中编译 C/C++ 原生代码
- Android Studio:如何在build.gradle中定义自定义宏(针对不同的构建变体),并让原生C / C++
- 在Android原生C++中使用Facemark opencv contrib
- 长双精度C++是IEEE二进制128的实现吗?
- CMake:Android Studio 原生活动项目无法在项目根目录之外找到第三方库
- Android NDK - C++ 异常会导致第三方原生库崩溃
- 如何在 gradle 原生项目中包含二进制库?
- 使用 Flutter 从 Android 上的原生编译共享库中调用函数
- exteranl原生构建问题,构建命令失败,android工作室
- build命令失败,外部原生问题android工作室
- 如何在electrolon项目中集成qt原生窗口
- Lua :在原生lua中编译,但在使用LuaJIT和sol2时C++出错
- 十六进制到浮点数 IEEE 754 双精度 c++
- 如何将.cpp C++原生库导入 Android Studio
- 原生 WebRTC 丢帧
- 如何使用 JNI 创建原生类?
- 如何为原生UI工具包扩展Ranorex?
- 如何从反应原生代码调用 C 函数?
- HDF5复合型原生与IEEE