2017-02-20 1 views
3

거대한 은하 카탈로그에서 특정 계산을 수행하는 컴파일 된 언어 (Fortran 95)로 코드를 개발 중입니다. 변경을 구현할 때마다 코드를 컴파일하고 실행하며 디스크에서 Galaxy 데이터로 ASCII 파일을 읽는 데 약 3 분이 걸립니다. 이것은 시간 낭비입니다.빠른 컴파일 사이에서 하드 드라이브의 데이터를 빠르게 읽는 속임수

IDL 또는 Matlab에서이 프로젝트를 시작했다면 배열 데이터를 포함하는 변수가 다른 컴파일 사이에 메모리에 저장되므로 다른 것입니다.

그러나 가짜 RAM 파티션이나 뭔가에있는 파일을 가지고있는 것처럼 디스크에서 읽기 편한 속도를 높이려면 뭔가를 할 수 있다고 생각합니다.

+0

내가 선택한 답변에 더 일치하도록 제목을 약간 변경했습니다. 그 대답은 원래 대답 100 % (RAM에 파티션을 수행하는 방법에 대한 단서 없음)에 맞지 않지만 녹색 태그를 부여하지 않으면 너무 유용합니다. 나는 특별히 RAM 디렉토리에 관한 다른 질문을 게시 할 것이다. – Mephisto

+1

몇 가지 실제 측정을 했습니까? 예를 들어 ASCII 데이터 형식을 구문 분석하는 것보다 병목 현상이 디스크 입출력이라는 것을 추측하고 있습니까? 램 디스크에 충분한 RAM이 있다고 가정하면 디스크 캐시를 충분히 사용할 수 있기 때문에 이미 어쨌든 메모리에서 대부분 읽는 것이 좋습니다. 이에 대한 대답은 받아 들여지고있다. –

+0

@ DanMašek 당신이 제안한 내용을 무시했지만 연속 로그인보다 코드가 처음 실행될 때 동일한 시간이 걸린다고 생각합니다. 또한 파일을 읽는 동안 TOP 명령은 100 % CPU 활동을 표시하지 않으므로 아마도 하드 드라이브 읽기에 문제가있는 것입니다. – Mephisto

답변

6

RAM 디스크의 세부 정보로 이동하는 대신 ASCII 데이터베이스에서 이진 데이터베이스로 전환하는 것이 좋습니다. 여기

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). 원본 파일에는 유형 (첫 번째 열은 문자, 두 번째는 정수, 다른 열은 부동 소수점입니다 ...)이 혼합되어 있습니다. 파생 된 유형 이진 파일을 작성할 때 어떻게 처리해야할지 모르겠습니다. 또한 합리적인 시간 내에 16000x16000 배의 정밀도 배열을 저장하고 읽을 수 있도록 바이너리로 간 다른 코드가 있습니다. – Mephisto

+1

그러나 파생 형식으로 ASCII 파일을 읽는 중 서식이 지정되지 않은 파일에서 작동 할 가능성이 높습니다. 예를 들어 정수 구성 요소와 실제 구성 요소 등을 읽습니다. 문제가 있으면 다른 질문을하십시오. – Ross

관련 문제