Есть ли способ открыть файлы hdf5 с флагом POSIX_FADV_DONTNEED? - PullRequest
2 голосов
/ 16 июня 2020
• 1000 . Мы работаем на машине linux (Ubuntu 18.04) с ОЗУ 192 ГБ. Мы заметили, что программа медленно заполняет кеш. Когда общий размер кэша достигает размера, сопоставимого с размером полной ОЗУ машины (свободная память почти равна нулю, но много «доступной» памяти), подкачка происходит, замедляя работу всех других приложений. Чтобы точно определить источник проблемы, мы написали отдельный минимальный пример, чтобы изолировать наши процедуры загрузки данных, но обнаружили, что проблема не зависит от каждой части нашего метода.

Мы попробовали: Создание numpy memmap и доступ к запрошенному фрагменту:

#on init:
f = h5py.File(tv_path, 'r')
hdf5_event_data = f["event_data"]
self.event_data = np.memmap(tv_path, mode="r", shape=hdf5_event_data.shape,                                           
                            offset=hdf5_event_data.id.get_offset(),dtype=hdf5_event_data.dtype)
self.e = np.ones((512,40,40,19))

#on __getitem__:
self.e = self.event_data[index,:,:,:19]
return self.e

Повторное открытие memmap при каждом вызове getitem:

#on __getitem__:
self.event_data = np.memmap(self.path, mode="r", shape=self.shape,
                                            offset=self.offset, dtype=self.dtype)
self.e = self.event_data[index,:,:,:19]
return self.e

Обращение к файлу h5 напрямую и преобразовывая в массив numpy:

#on init:
f = h5py.File(tv_path, 'r')
hdf5_event_data = f["event_data"]
self.event_data = hdf5_event_data
self.e = np.ones((512,40,40,19))

#on __getitem__:
self.e = self.event_data[index,:,:,:19]
return self.e

Мы также пробовали описанные выше подходы в среде pytorch Dataset / Dataloader, но это не имело никакого значения.

Мы наблюдаем высокую фрагментацию памяти, о чем свидетельствует / proc / buddyinfo. Сбрасывание кеша через синхронизацию; echo 3> / proc / sys / vm / drop_caches не помогает во время работы приложения. Очистка кеша перед запуском приложения устраняет поведение подкачки до тех пор, пока кеш снова не съест всю память - и подкачка не начнется снова. В конце концов, когда запрашивается новая память, подкачка выполняется, хотя большая часть памяти все еще «доступна».

Таким образом, мы обратились к способам изменения поведения среды Linux в отношении кэширования файлов и нашли этот пост. Есть ли способ вызвать флаг POSIX_FADV_DONTNEED при открытии файла h5 в python или его части, к которой мы обращались через numpy memmap, чтобы этого накопления кеша не происходило? В нашем случае мы не будем повторно посещать это конкретное местоположение файла в течение длительного времени (пока мы не получим доступ ко всем остальным «фрагментам» файла)

1 Ответ

1 голос
/ 16 июня 2020

Вы можете использовать os.posix_fadvise, чтобы сообщить ОС, как будут использоваться регионы, которые вы планируете загружать. Это, естественно, требует небольшой настройки на низком уровне, чтобы определить ваш файловый дескриптор и получить представление о регионах, которые вы планируете читать.

Самый простой способ получить файловый дескриптор - предоставить его самому:

pf = open(tv_path, 'rb')
f = h5py.File(pf, 'r')

Теперь вы можете установить совет. Для всего файла:

os.posix_fadvise(os.fileno(pf), 0, f.id.get_filesize(), os.POSIX_FADV_DONTNEED)

Или для конкретного набора данных:

os.posix_fadvise(os.fileno(pf), hdf5_event_data.id.get_offset(),
                 hdf5_event_data.id.get_storage_size(), os.POSIX_FADV_DONTNEED)

Другие элементы, на которые следует обратить внимание

H5py делает свое собственное кеширование фрагментов . Вы можете попробовать отключить это:

f = h5py.File(..., rdcc_nbytes=0)

В качестве альтернативы вы можете попробовать использовать один из других драйверов , предоставленных в h5py, например 'sec2':

f = h5py.File(..., driver='sec2')
...