Уменьшить размер выходных файлов на Фортране - PullRequest
0 голосов
/ 28 мая 2018

Я хочу минимизировать размер выходных файлов в FORTRAN без потери каких-либо данных.Чтобы найти лучший способ сделать это, я написал программу:

      program test                                                              

      character(len=255) format

1     format(9i3)                                                               

c FORMATTED          
      open(99,file='form1.txt',form='formatted')                                
      do i=1,1                                                            
        write(99,1) 1, 2, 3, 4, 5, 6, 7, 8, 9                                   
      enddo                                                                     
      close(99)                                                                 

c UNFORMATTED          
      open(98,file='form2.txt',form='unformatted')                              
      do i=1,1                                                            
        write(98) 1, 2, 3, 4, 5, 6, 7, 8, 9                                     
      enddo                                                                     
      close(98)                                                                 

c DIRECT ACCESS          
      nrec=sizeof(i)*9                                                          
      open(97,file='form3.txt',form='unformatted',                              
     &     access='direct',recl=nrec)                                           
      do i=1,1                                                            
        write(97,rec=i) 1, 2, 3, 4, 5, 6, 7, 8, 9                               
      enddo                                                                     
      close(97)                                                                 

      call system('ls -lh form?.txt')                                           
      end

Это создаст три файла с одной записью каждый.Вывод этой программы:

-rw-r--r--. 1 user users  28 May 27 17:10 form1.txt
-rw-r--r--. 1 user users  44 May 27 17:10 form2.txt
-rw-r--r--. 1 user users  36 May 27 17:10 form3.txt

с веб-сайт Oracle :

Если FORM = 'UNFORMATTED', каждой записи предшествует и заканчиваетсяINTEGER * 4 рассчитывают, делая каждую запись на 8 символов длиннее, чем обычно.Это соглашение не распространяется на другие языки, поэтому оно полезно только для обмена данными между программами FORTRAN.

Мои вопросы:

  1. Почему существует разница в 16 байтов(не 8 байтов, как упоминалось в предыдущей цитате) между form1.txt и form2.txt?Обратите внимание, что размер file1.txt зависит от формата (например, если я изменю строку format(9i3) на format(9i4), размер файла file1.txt увеличится на 9 байт).

и мой главный вопрос:

У меня есть большие файлы данных (больше 100 ГБ) с пятью столбцами и миллионами строк.Каков наилучший метод в FORTRAN для уменьшения размера моих выходных файлов (возможно, запись в двоичном виде)?

Подобный мой вопрос: Лучший способ записать большой массив в файл на фортране?Текст против другого

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

В основном ваш формат 9i3 означает, что каждое число занимает в файле ровно 3 байта.Это 27 байтов, плюс один для возврата каретки составляет 28.

Но вы можете хранить в этом формате только номера до 999, и даже тогда числа свыше 99 будут смешиваться вместе.

Прямой доступхранит двоичное представление целых чисел, таким образом, 32 бита или 4 байта на число.Всего 36 байтов.Это больше, чем 28 вашей отформатированной версии, но она может работать со всеми целыми числами, до 2 147 483 647 и до -2 147 483 648, оставаясь при этом того же размера.(Если вам нужна такая же гибкость в отформатированной версии, вам потребуется формат 9I11 для общего объема в 100 байт).

Неформатированная версия немного посередине, она все еще хранит некоторые метаданные, то естьпочему он немного больше, чем прямой доступ, но, как и прямой доступ, вы можете хранить все целые числа таким образом, занимая одинаковое количество места.

Что касается вашего второго вопроса, то, что вы должны использовать, зависит отмного вещей.Как вы заметили, если ваши целые числа всегда между 0 и 99, то их строковое представление меньше, чем их двоичное представление.Но если вам нужно 4 цифры (включая знак), двоичное представление становится меньше.Я, вероятно, также должен указать, что если ваши числа невелики, вы можете также объявить их как 8- или 16-битные целые числа, что будет означать, что они занимают только один или два байта соответственно.

Двоичное представлениетакже быстрее, так как числа не нужно преобразовывать между двоичным и строковым.

Но для размеров, о которых вы говорите, может оказаться полезным изучить другие форматы файлов, например NetCDF , который имеет несколько методов сжатия данных.

0 голосов
/ 28 мая 2018

Не обращаясь непосредственно к вашему вопросу, я хотел бы отметить, что существует ограничение на размер файла, если вы используете двоичные данные.Даже если используется наиболее плотное представление хранилища без каких-либо контрольных сумм или мета-информации, например, о длине записи, вам придется хранить sizeof (тип данных) * num_entries bytes.

Вы можете использовать алгоритм быстрого сжатия, такой как blosc , даже способный превзойти C-RAM-to-RAM memcpy().Эффективность и производительность, очевидно, сильно зависят от распределения ваших данных, но могут достигать десятков ГБ / с в реальных приложениях.

100 ГБ - это, вероятно, много данных, чтобы поместиться в оперативную память вашей машины.Можно либо разбить файлы на части вручную, либо использовать библиотеку, например HDF5 .HDF5 обеспечивает сжатое порционное хранилище для в основном произвольных объемов данных с высокой производительностью.Тем не менее, включение большой библиотеки может быть трудоемким, даже если существует HDF5 Fortran API .

...