Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 在成功编译之间更快地从硬盘读取数据的技巧_Arrays_Fortran_Mount_Ramdisk - Fatal编程技术网

Arrays 在成功编译之间更快地从硬盘读取数据的技巧

Arrays 在成功编译之间更快地从硬盘读取数据的技巧,arrays,fortran,mount,ramdisk,Arrays,Fortran,Mount,Ramdisk,我正在使用编译语言(Fortran 95)开发代码,该语言在一个巨大的星系目录上进行某些计算。每次实现一些更改时,我都编译并运行代码,从磁盘读取包含galaxy数据的ASCII文件大约需要3分钟。这是浪费时间 如果我在IDL或Matlab中启动这个项目,那么情况就不同了,因为包含数组数据的变量将在不同编译之间保存在内存中 然而,我认为可以采取一些措施来加速从磁盘读取令人不安的数据,比如将文件放在伪RAM分区中或其他什么地方。我建议您从ASCII数据库切换到二进制数据库,而不是详细讨论RAM磁盘。

我正在使用编译语言(Fortran 95)开发代码,该语言在一个巨大的星系目录上进行某些计算。每次实现一些更改时,我都编译并运行代码,从磁盘读取包含galaxy数据的ASCII文件大约需要3分钟。这是浪费时间

如果我在IDL或Matlab中启动这个项目,那么情况就不同了,因为包含数组数据的变量将在不同编译之间保存在内存中


然而,我认为可以采取一些措施来加速从磁盘读取令人不安的数据,比如将文件放在伪RAM分区中或其他什么地方。

我建议您从ASCII数据库切换到二进制数据库,而不是详细讨论RAM磁盘。这是一个非常简单的例子。。。随机数数组,存储为ASCII(ASCII.txt)和二进制日期(binary.bin):

以下是尺寸方面的结果:

 :> ls -lah ASCII.txt binary.bin 
-rw-rw-r--. 1 elias elias 2.5G Feb 20 20:59 ASCII.txt
-rw-rw-r--. 1 elias elias 763M Feb 20 20:59 binary.bin
因此,就存储而言,您可以节省约3.35倍的存储空间。 现在有趣的部分来了:把它读回

program readArr
  use,intrinsic :: ISO_Fortran_env, only: REAL64
  implicit none
  real(REAL64),allocatable :: tmp(:,:)
  integer :: uFile, i
  integer :: count_rate, iTime1, iTime2

  allocate( tmp(10000,10000) )

  ! Get the count rate
  call system_clock(count_rate=count_rate)

  ! Formatted write  
  open(unit=uFile, file='ASCII.txt',form='formatted', &
       status='old',action='read')

  call system_clock(iTime1)
  do i=1,size(tmp,1)
    read(uFile,*) tmp(:,i)
  enddo !i
  call system_clock(iTime2)
  close(uFile)
  print *,'ASCII  read ',real(iTime2-iTime1,REAL64)/real(count_rate,REAL64)

  ! Unformatted write  
  open(unit=uFile, file='binary.bin',form='unformatted', &
       status='old',action='read')
  call system_clock(iTime1)
  read(uFile) tmp
  call system_clock(iTime2)
  close(uFile)
  print *,'Binary read ',real(iTime2-iTime1,REAL64)/real(count_rate,REAL64)

end program
结果是

 ASCII  read    37.250999999999998     
 Binary read    1.5460000000000000   
因此,系数>24


因此,请先切换到二进制文件格式,而不要考虑其他任何事情

当然,有许多二进制格式更适合复杂数据,并且比简单的Fortran二进制文件更易于移植。在这些当中,我建议你考虑HDF5。这是一个很棒的答案,对很多人(1)都是有用的,但是原始文件有多种类型(第一列是字符,第二是整数,其他列是浮点……),并且我定义了派生类型。我不知道在编写二进制文件时如何处理这个问题。我还使用了其他代码,其中我使用了二进制代码,以便能够在合理的时间内存储和读取16000x16000双精度数组。但是,将ASCII文件读入派生类型可能适用于未格式化的文件。例如,读取整数分量,然后读取实分量,依此类推。如果你有问题,可以问另一个问题。@Mephisto如果结构正确,那么这个结构就可以写出来。所以,在一小块上试试。显然,你将需要一个二进制到ASCII和ASCII到二进制的接口来与你的社区的其他成员交互,但这应该很容易。为了更好地匹配我选择的答案,我稍微更改了标题。这个答案不符合我原来的答案100%(没有关于如何在RAM中进行分区的线索),但如果不给它绿色标签,它就太有用了。我将专门发布另一个关于RAM目录的问题。您是否进行了一些实际测量,或者您只是猜测瓶颈是磁盘I/O,而不是解析ASCII数据格式?假设您有足够的RAM存储一个RAM磁盘,那么您可能也有足够的RAM存储一个磁盘缓存,所以您很有可能已经基本上从内存中读取了。公认的答案暗示了这一点。@DanMašek我忽略了您建议的细节,但我认为登录后第一次执行代码所用的时间与连续读取的时间相同。此外,在读取文件时,TOP命令不会显示100%的cpu活动,因此问题可能在于硬盘驱动器读取。
 ASCII  read    37.250999999999998     
 Binary read    1.5460000000000000