Производительность нескольких фрагментированных наборов данных в одном файле HDF5?

#hdf5 #h5py

#hdf5 #h5py

Вопрос:

Предположим (я добавляю пример кода ниже), что я создаю несколько фрагментированных наборов данных в одном файле HDF5 и начинаю добавлять данные к каждому набору данных в случайном порядке. Поскольку HDF заранее не знает, какой размер выделить для каждого набора данных, я бы подумал, что каждая операция добавления (или, возможно, буфер набора данных при заполнении) добавляется непосредственно в файл HDF5. Если это так, данные каждого набора данных будут чередоваться с данными из других наборов данных и будут распределены порциями по всему файлу HDF5.

Мой вопрос: если приведенное выше описание более или менее точное, не повлияет ли это отрицательно на производительность операций чтения, выполняемых позже из этого файла, и, возможно, также на размер файла, если требуется больше записей метаданных? И (соответственно), если существует возможность хранить каждый набор данных в отдельном файле, не было бы лучше сделать это с точки зрения производительности чтения?

Вот пример того, как может быть создан файл HDF5, который я описал в начале:

 import h5py, numpy as np

dtype1 = np.dtype( [ ('t','f8'), ('T','f8') ] )
dtype2 = np.dtype( [ ('q','i2'), ('Q','f8'), ('R','f8') ] )
dtype3 = np.dtype( [ ('p','f8'), ('P','i8') ] )

with h5py.File('foo.hdf5','w') as f:
    dset1 = f.create_dataset('dset1', (1,), maxshape=(None,), dtype=h5py.vlen_dtype(dtype1))
    dset2 = f.create_dataset('dset2', (1,), maxshape=(None,), dtype=h5py.vlen_dtype(dtype2))
    dset3 = f.create_dataset('dset3', (1,), maxshape=(None,), dtype=h5py.vlen_dtype(dtype3))
    for _ in range(10):
        random_lengths = np.random.randint(low=1, high=10, size=3)

        d1 = np.ones( (random_lengths[0],), dtype=dtype1 )
        dset1[-1] = d1
        dset1.resize( (dset1.shape[0] 1,) )

        d2 = np.ones( (random_lengths[1],), dtype=dtype2 )
        dset2[-1] = d2
        dset2.resize( (dset2.shape[0] 1,) )

        d3 = np.ones( (random_lengths[2],), dtype=dtype3 )
        dset3[-1] = d3
        dset3.resize( (dset3.shape[0] 1,) )
  

Я знаю, что мог бы попробовать оба способа (один файл с несколькими наборами данных или несколько файлов с отдельными наборами данных) и рассчитать время, но результат может зависеть от специфики используемых данных примера, и я предпочел бы получить более общий ответ на этот вопрос и, возможно, некоторое представление о том, как HDF5 / h5py работают внутрив этом случае.

Комментарии:

1. Если я понимаю, вас беспокоит то, что каждый набор данных не является непрерывным на диске. Это проблема для любого файла, созданного любым приложением. Операционная система управляет дисковым вводом-выводом на аппаратном уровне. В результате нет способа гарантировать непрерывность файла или набора данных на диске при их выделении. Вероятно, это будет, если есть непрерывный свободный блок, который достаточно велик, когда он выделяется. (Вы можете увидеть это при повреждении диска.) Компьютеры обычно имеют дело с фрагментированными файлами (особенно в многопользовательских системах, таких как HPC). Скорость ввода-вывода в основном определяется скоростью чтения / записи диска.

2. Верно, меня беспокоит непрерывность данных на диске. И, конечно, трудно избежать фрагментации на уровне файловой системы, но я сомневаюсь, что это делает фрагментацию на уровне HDF не проблемой. Если бы это было так, то почему HDF различает непрерывное и фрагментированное хранилище? Фрагментированное хранилище более гибкое, поэтому разве производительность не является единственной причиной выбора contiguous? Возможно, это так, потому что фрагменты HDF добавляют дополнительную косвенность поверх фрагментации файловой системы, но главным образом потому, что я подозреваю, что накладные расходы на обслуживание HDF (или, по крайней мере, h5py) значительно выше, чем у файловой системы.