2013-02-28 17 views
5

Tôi chỉ chọn lên HDF5 và tôi hơi bối rối về sự khác biệt giữa việc tạo dữ liệu cho bộ nhớ và tạo dữ liệu cho tệp. Có gì khác biệt?HDF5 Loại hợp chất Gốc so với IEEE

Trong this dụ, tạo ra một kiểu dữ liệu hợp chất đòi hỏi dữ liệu được tạo ra trong bộ nhớ và được đặt trong file:

/* 
* 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); 

Tuy nhiên, trong một ví dụ khác here, tác giả cũng tạo ra một dữ liệu hợp chất cho tệp, chỉ định một kiểu dữ liệu khác. Ví dụ, khi tạo kiểu dữ liệu cho bộ nhớ, serial_no sử dụng loại H5T_NATIVE_INT, nhưng khi tạo kiểu dữ liệu cho tệp, serial_no đã sử dụng H5T_STD_I64BE. Tại sao anh ta làm việc này?

/* 
* 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); 

Sự khác nhau giữa hai phương pháp này là gì?

Trả lời

5

Từ http://www.hdfgroup.org/HDF5/doc/UG/UG_frame11Datatypes.html:

H5T_NATIVE_INT tương ứng với một loại C int. Trên một máy tính dựa trên Intel, kiểu này giống như H5T_STD_I32LE, trong khi trên một hệ thống MIPS, nó sẽ tương đương với H5T_STD_I32BE.

Có nghĩa là, H5T_NATIVE_INT có bố cục bộ nhớ khác nhau trên các loại bộ vi xử lý khác nhau. Nếu dữ liệu của bạn chỉ được sử dụng trong bộ nhớ, điều đó có nghĩa là dữ liệu của bạn sẽ không bị loại bỏ khỏi máy này, bạn có thể muốn sử dụng H5T_NATIVE_INT để có hiệu suất tốt hơn.

Nhưng nếu dữ liệu của bạn sẽ được lưu vào tệp và sẽ được sử dụng bởi các hệ thống khác nhau, bạn phải chỉ định loại int nhất định để dữ liệu của bạn có thể đọc được chính xác, ví dụ: H5T_STD_I64BE hoặc H5T_STD_I32LE. Nếu bạn sử dụng H5T_NATIVE_INT và bạn đã tạo tệp dữ liệu trên PC dựa trên Intel, số sẽ được lưu dưới dạng H5T_STD_I32LE. Khi tập tin này được sử dụng bởi một hệ thống MIPS, nó sẽ đọc số như H5T_STD_I32BE, mà không được mong đợi.

+0

cảm ơn bạn, đó là rất rõ ràng – foboi1122

+0

từ giải thích của tôi: nó là ok để có loại tập tin với NATIVE_some_type; đó là trách nhiệm của khách hàng khi lập bản đồ khi đọc lại nội dung. nói cách khác: "Khi tập tin này được sử dụng bởi một hệ thống MIPS, nó sẽ đọc số như H5T_STD_I32BE, mà không được mong đợi." là không đúng sự thật; khách hàng nên đọc lại loại tệp và tạo bố cục bộ nhớ tương ứng. Máy khách nên mong đợi thứ tự byte không khớp và giảm thiểu nó với ánh xạ thích hợp. Ví dụ này chứng minh rằng thứ tự byte/bố cục tệp được tách riêng khỏi thứ tự/bố trí byte của máy chủ (bộ nhớ). –

+0

@StevenVarga Nếu sử dụng H5T_NATIVE_INT, bạn không biết nó là endian lớn hay nhỏ endian, trừ khi bạn đặt một lá cờ ở đâu đó nói thứ tự byte là gì. Ngay cả khi bạn biết thứ tự byte thực sự, nó không phải là nỗ lực tầm thường để chuyển đổi tất cả dữ liệu sau khi chúng được nạp. Và việc bảo trì mã cũng khó khăn. Quan tâm làm gì? Tại sao không sử dụng thứ tự byte rõ ràng khi lưu vào tệp? – Chen

0

Câu trả lời khác ở đây thiếu một số ý tưởng chính và làm cho việc sử dụng các kiểu dữ liệu HDF5 có vẻ khó hơn.

Để bắt đầu, các loại NATIVE chỉ đơn giản là bí danh cho những gì các loại C ánh xạ trên nền tảng đó (điều này được phát hiện khi thư viện HDF5 được xây dựng). Nếu bạn sử dụng chúng trong mã của bạn và nhìn vào tệp bạn đã tạo bằng công cụ h5dump, bạn sẽ không thấy kiểu dữ liệu NATIVE mà thay vào đó sẽ thấy kiểu dữ liệu thực (H5T_STD_I32LE hoặc whatnot). Các kiểu NATIVE này được thừa nhận một chút khó hiểu, nhưng chúng thuận tiện cho việc ánh xạ giữa các kiểu C và các kiểu dữ liệu HDF5 mà không cần phải biết thứ tự byte của hệ thống mà bạn đang sử dụng.

Quan niệm sai lầm khác mà tôi muốn làm rõ là thư viện sẽ chuyển đổi các loại cho bạn khi hợp lý để làm như vậy. Nếu tập dữ liệu chứa các giá trị H5T_STD_I32BE và bạn khai báo bộ đệm I/O là H5T_NATIVE_INT trên một hệ thống nhỏ, thư viện HDF5 sẽ chuyển đổi số nguyên lớn nhất thành số nguyên nhỏ trong bộ nhớ cho bạn. Bạn không cần phải thực hiện trao đổi byte trên của riêng bạn.

Đây là một cách đơn giản để suy nghĩ về nó:

  • Bạn khai báo của một tập dữ liệu kiểu dữ liệu lưu trữ khi bạn gọi H5Dcreate().
  • Bạn khai báo kiểu dữ liệu bộ đệm I/O khi bạn gọi H5Dread() và H5Dwrite().

Một lần nữa, nếu các chuyển đổi loại khác nhau này là hợp lý, dữ liệu sẽ được chuyển đổi trong khi đọc/ghi cuộc gọi.

Lưu ý rằng chuyển đổi loại này có thể có ý nghĩa hiệu suất trong các ứng dụng thời gian quan trọng. Nếu nền tảng nơi dữ liệu sẽ được viết và đọc khác nhau theo thứ tự byte hoặc kích thước từ, bạn có thể muốn đặt rõ ràng kiểu dữ liệu thay vì sử dụng các bí danh NATIVE để bạn có thể buộc chuyển đổi diễn ra trên nền tảng ít quan trọng hơn.

Ví dụ: Giả sử bạn có nhà văn BE và trình đọc LE và dữ liệu đến chậm nhưng đọc phải nhanh nhất có thể. trong trường hợp này, bạn sẽ muốn tạo rõ ràng tập dữ liệu của mình để lưu trữ dữ liệu H5T_STD_I32LE để các chuyển đổi kiểu dữ liệu xảy ra trên trình ghi.

Điều cuối cùng - Tốt hơn là sử dụng macro HOFFSET (s, m) thay vì tính toán bù trừ bằng tay khi xây dựng các loại hợp chất. Nó dễ bảo trì hơn và mã của bạn trông đẹp hơn.

Nếu bạn muốn biết thêm thông tin về kiểu dữ liệu HDF5, hãy kiểm tra chương 6 của hướng dẫn của người dùng ở đây: https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html

Bạn cũng có thể kiểm tra các tài liệu H5T API trong cuốn hướng dẫn tài liệu tham khảo ở đây: https://support.hdfgroup.org/HDF5/doc/RM/RM_H5Front.html