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