2017-02-20 2 views
3

私は巨大な銀河カタログ上の特定の計算を行いコンパイル言語(Fortran 95の)を使用してコードを開発しています。いくつかの変更を実装するたびに、コードをコンパイルして実行し、ディスクから銀河のデータをASCIIファイルで読み取るだけで約3分かかります。これは時間の無駄です。 トリック

は、配列データを含む変数が異なるコンパイル間のメモリに保持されるので、それは、異なるだろう、私はIDLまたは、MATLABでこのプロジェクトを始めました。

はしかし、私は何かが偽のRAMパーティションか何かでファイルを持っているように、ディスクからの読み取り狼狽することをスピードアップするために行うことができると思います。代わりに、私はあなたがバイナリのものにASCIIデータベースに切り替える提案するRAMディスクの詳細に入るの

+0

私はより良い私が選出されてきた答えを一致させるために、わずかにタイトルを変更しました。その答えは私の元の答え100%(RAMにパーティションを作成する方法の手がかりはありません)に合っていませんが、緑のタグを付けないとあまり役に立ちません。私は特にRAMディレクトリに関する別の質問を投稿します。 – Mephisto

+1

いくつかの実際の測定を行ったことがありますか、たとえば、ASCIIデータ形式の解析ではなく、ボトルネックがディスクI/Oであると推測していますか?あなたがRAMディスク用に十分なRAMを持っていると仮定すると、おそらくディスクキャッシュも十分に利用できるはずです。だから、とにかくメモリから大部分を読み込んでいる可能性は十分です。受け入れられた答えは、これが事実であることを示唆している。 –

+0

@DanMašekあなたが提案した内容を無視しますが、ログイン後に初めてコードを実行するときには、連続した読み込みと同じ時間がかかると思います。また、ファイルが読んでいる間、TOPコマンドは100%CPUの活動を示さないので、おそらく問題はハードドライブの読書にあります。 – Mephisto

答えて

6

。ここで

program writeArr 
    use,intrinsic :: ISO_Fortran_env, only: REAL64 
    implicit none 
    real(REAL64),allocatable :: tmp(:,:) 
    integer :: uFile, i 

    allocate(tmp(10000,10000)) 

    ! Formatted read 
    open(unit=uFile, file='ASCII.txt',form='formatted', & 
     status='replace',action='write') 
    do i=1,size(tmp,1) 
    write(uFile,*) tmp(:,i) 
    enddo !i 
    close(uFile) 

    ! Unformatted read 
    open(unit=uFile, file='binary.bin',form='unformatted', & 
     status='replace',action='write') 
    write(uFile) tmp 
    close(uFile) 

end program 

サイズの面で結果がされています:ここでは非常に単純化した例... 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倍です!

ので、代わりの何か他のものの考え方、最初のバイナリファイル形式に切り替えてください。

+0

もちろん、複雑なデータに適した多くのバイナリ形式があり、単純なFortranバイナリファイルよりもはるかに移植性があります。その中で私はあなたがHDF5を検討することをお勧めします。 –

+0

これは多くの人にとって便利な素晴らしい答えですが(+1)、元のファイルには種類が混在しています(第1列は文字、第2列は整数、他の列は浮動小数点です...)派生型私は、バイナリファイルを書くときにそれをどのように扱うべきか分かりません。妥当な時間内に16000x16000の倍精度配列を格納して読み込めるようにするために、バイナリに移動したコードもあります。 – Mephisto

+1

しかし、ASCIIファイルを派生型に読み込んでいた場合、フォーマットされていないファイルでもうまく機能します。たとえば、整数コンポーネント、実際のコンポーネントなどを読み取ります。問題がある場合は、別の質問をしてください。 – Ross

関連する問題