2013-02-28 9 views
5

Po prostu wychwytuję HDF5 i jestem nieco zdezorientowany różnicą między tworzeniem danych dla pamięci i tworzeniem danych dla pliku. Co za różnica?HDF5 Złożony typ Native vs IEEE

W this przykład tworzenia danych typu związek wymaga danych, które mają być tworzone w pamięci i umieszczone w pliku:

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

Jednak w innym przykładzie here, autor tworzy również dane związek do plik, który określa inny typ danych. Na przykład przy tworzeniu typu danych dla pamięci, serial_no używany typ H5T_NATIVE_INT, ale przy tworzeniu typu danych dla pliku, serial_no używany H5T_STD_I64BE. Czemu on to robi?

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

Jaka jest różnica między tymi dwoma metodami?

Odpowiedz

5

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

H5T_NATIVE_INT odpowiada typu C int. Na komputerze z procesorem Intela ten typ jest taki sam jak H5T_STD_I32LE, podczas gdy w systemie MIPS byłby to odpowiednik H5T_STD_I32BE.

To znaczy, że H5T_NATIVE_INT ma inny układ pamięci dla różnych typów procesorów. Jeśli twoje dane są używane tylko w pamięci, co oznacza, że ​​twoje dane nie zostaną usunięte z tego komputera, możesz użyć H5T_NATIVE_INT dla lepszej wydajności.

Ale jeśli twoje dane zostaną zapisane do pliku i będą używane przez różne systemy, musisz podać określony typ int, aby dane były poprawnie czytane, np. H5T_STD_I64BE lub H5T_STD_I32LE. Jeśli korzystasz z H5T_NATIVE_INT i utworzonego pliku danych na komputerze z procesorem Intel, numer zostanie zapisany jako H5T_STD_I32LE. Kiedy ten plik jest używany przez system MIPS, odczyta on numer jako H5T_STD_I32BE, co nie jest oczekiwane.

+0

podziękowaniem ty, to było bardzo zrozumiałe, – foboi1122

+0

z mojej interpretacji: dobrze jest mieć typ pliku z NATIVE_some_type; klient jest odpowiedzialny za wykonanie mapowania podczas odczytywania treści. innymi słowy: "Kiedy ten plik jest używany przez system MIPS, odczyta on numer jako H5T_STD_I32BE, co nie jest oczekiwane." to nie jest prawda; klient powinien odczytać typ pliku z powrotem i odpowiednio utworzyć układ pamięci. Klient powinien oczekiwać niedopasowania kolejności bajtów i złagodzić je przy pomocy odpowiedniego odwzorowania. Przykład pokazuje, że kolejność/układ bajtów pliku jest oddzielona od kolejności/układu bajtów hosta (pamięci). –

+0

@StevenVarga Jeśli użyjesz H5T_NATIVE_INT, nie wiesz, że jest to duży endian lub little endian, chyba że umieścisz flagę gdzieś mówiącą, jaka jest kolejność bajtów. Nawet jeśli znasz faktyczną kolejność bajtów, nie jest trywialnym wysiłkiem, aby przekonwertować wszystkie dane po ich załadowaniu. Utrzymanie kodu jest również trudne. Po co się męczyć? Dlaczego nie używać jawnej kolejności bajtów podczas zapisywania do pliku? – Chen

0

W drugiej odpowiedzi brakuje niektórych kluczowych pomysłów i sprawia, że ​​używanie typów danych HDF5 wydaje się trudniejsze niż jest.

Po pierwsze, typy NATIVE są po prostu aliasami dla typów map C na tej platformie (jest to wykrywane podczas budowania biblioteki HDF5). Jeśli użyjesz ich w kodzie i spojrzysz na plik utworzony za pomocą narzędzia h5dump, nie zobaczysz typu NATIVE, ale zamiast tego zobaczysz prawdziwy typ danych (H5T_STD_I32LE lub inny). Te typy NATIVE są wprawdzie nieco mylące, ale są wygodne do mapowania pomiędzy typami C i typami HDF5 bez konieczności znajomości kolejności bajtów systemu, na którym się znajdujesz.

Innym błędnym przekonaniem, które chcę wyjaśnić, jest to, że biblioteka konwertuje typy, jeśli jest to uzasadnione. Jeśli zbiór danych zawiera wartości H5T_STD_I32BE i deklarujesz, że bufor I/O ma być H5T_NATIVE_INT na systemie little-endian, biblioteka HDF5 skonwertuje dla Ciebie wielko-endianowe zmienne danych liczbowych na liczby całkowite w pamięci little-endian. Nie powinieneś wymagać samodzielnej zamiany bajtów.

Oto prosty sposób, aby myśleć o tym:

  • zadeklarować przechowywania typ danych w zbiorze danych kiedy zadzwonić H5Dcreate().
  • Deklarujesz typ danych bufora we/wy podczas wywoływania funkcji H5Dread() i H5Dwrite().

Ponownie, jeśli te różne i typowe konwersje są uzasadnione, dane zostaną przekonwertowane podczas wywołań do odczytu/zapisu.

Należy pamiętać, że konwersja tego rodzaju może mieć wpływ na wydajność w aplikacjach o krytycznym czasie. Jeśli platformy, na których dane będą zapisywane i odczytywane, różnią się kolejnością bajtów lub rozmiarem słowa, możesz wyraźnie ustawić typ danych zamiast używać aliasów NATIVE, aby można było wymusić konwersję na mniej ważnej platformie.

Przykład: Załóżmy, że masz pisarza BE i czytnik LE, a dane przychodzą powoli, ale odczyty muszą być tak szybkie, jak to możliwe. w takim przypadku należy jawnie utworzyć zestaw danych do przechowywania danych H5T_STD_I32LE, aby konwersje typów danych miały miejsce w programie piszącym.

Ostatnia rzecz - Lepiej używać makra HOFFSET (s, m) zamiast obliczać przesunięcia ręcznie przy konstruowaniu typów złożonych. Jest bardziej łatwy w utrzymaniu, a twój kod będzie ładniejszy.

Jeśli chcesz uzyskać więcej informacji na temat typów danych hdf5, sprawdź rozdział 6 podręcznika użytkownika tutaj: https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html

Można również sprawdzić docs H5T API w podręczniku tutaj: https://support.hdfgroup.org/HDF5/doc/RM/RM_H5Front.html

Powiązane problemy