【问题标题】:Reading an unformatted stream binary file using MPI I/O in Fortran在 Fortran 中使用 MPI I/O 读取未格式化的流二进制文件
【发布时间】:2018-11-29 07:20:03
【问题描述】:

我有一个大小约为 60GB 的未格式化流二进制文件,我在串行代码中读取如下;

   parameter(nsea=120445)
   real*4 p(nsea,nsea)
   open(10,file='my_file.grd'  &
   & ,status='old',access='stream',form='unformatted')
   read(10)((p(ibk,jbk),jbk=1,nsea),ibk=1,nsea)
   close(10)

由于读取此文件需要大量时间,我想使用 MPI I/O 并行化这部分代码。我正在尝试使用mpi_file_set_viewmpi_file_read 选项来做到这一点。有人可以指导我有效地做到这一点吗? 在读取并存储参数p(nsea,nsea) 之后,我想在其余代码中传递整个数组以进行一些矩阵运算。

【问题讨论】:

  • 欢迎您,请收下欢迎邮件tour 并阅读How to Ask。你不应该寻求指导,这对于 Stack Overflow 来说可能过于宽泛,而应该问一个可以回答的问题。你有并行文件系统吗?使用 MPI,您不会并行化部分代码,而是并行化整个代码。其余代码在 MPI 中吗?
  • 是的,我有一个并行文件系统(光泽)。我的想法是在使用 MPI I/O 读取数组后,将其存储为全维度的二维数组。然后将其用于进一步的矩阵运算(这部分是串行的,计算时间并不长)
  • 我不明白。你想如何存储它?
  • 正如您在我的序列号中看到的,我最终需要一个维度为 (nsea x nsea) 的矩阵“p”。我想要的是优化读取文件的时间。请。建议我是否想错了方向。
  • 但是在 MPI 中你会将它读入许多进程中,每个进程都会有它的一部分。您是否有足够的内存将它们收集到一个进程中?

标签: io fortran mpi mpi-io


【解决方案1】:

我在我的电脑上尝试了一个简单的示例代码复制器,它具有 32 GB 内存,用于 27 Gb 测试文件。用“gFortran stream.f90 -o stream.exe”编译,跑了320秒,是不是单线程太慢了? (由于磁盘缓冲,这种测试方法可能会出现问题,但当文件大小 + 内存需求超过安装的内存时应该不会出现问题) 您可能希望通过包含更多错误测试(stat=、iostat=)来扩展我在下面列出的方法。

! Program to test stream I/O for large file
!
   integer*8 :: nsea = 85000 ! 40000 > 6gb ! 85000 > 27gb ! 120445 > 54 gb
   real*4, allocatable :: p(:,:)
!
   integer*8 :: ibk,jbk, nij
   integer*4 :: i,j, stat
   real*4    :: err, gb
   real*8    :: sec, start
!
! Create file
    call Elapse_Time (start)
    call Delta_Time (sec)
   allocate ( p(nsea,nsea), stat=stat )
   nij = size( p, kind=8 )
   gb  = nij ; gb = gb * 4. / (1024.**3)
   write (*,21) 'size p = ',size( p, kind=8 ), gb,' Gb : stat= ',stat
!
   forall (i=1:nsea,j=1:nsea) P(i,j) = i+j
    call Delta_Time (sec)
    write (*,22) sec,' initialised'
!
   open (unit=11, file='test_file.grd', iostat=stat, &
         status='unknown', access='stream', form='unformatted')
    call Delta_Time (sec)
    write (*,22) sec, ' open : iostat= ',stat
!
   write (11,iostat=stat) (( p(ibk,jbk), ibk=1,nsea), jbk=1,nsea)
   close (11)
   deallocate (p)
    call Delta_Time (sec)
    write (*,22) sec, ' written : iostat= ',stat
!
! Read file
   allocate ( p(nsea,nsea), stat=stat )
   write (*,21) 'size p = ',size( p, kind=8 ), gb,' Gb : stat= ',stat
!
   open (unit=12, file='test_file.grd', iostat=stat,  &
         status='unknown', access='stream', form='unformatted')
    call Delta_Time (sec)
    write (*,22) sec, ' open : iostat= ',stat
!
   read (12,iostat=stat) (( p(ibk,jbk), ibk=1,nsea), jbk=1,nsea)
   close (12)
    call Delta_Time (sec)
    write (*,22) sec,' read : iostat= ',stat
!
   err = 0
   do j=1,nsea
     do i=1,nsea
       err = max ( err, P(i,j)-i-j )
     end do
   end do
   deallocate (p)
    call Delta_Time (sec)
    write (*,23) sec, ' err= ', err
!
   call Elapse_Time (sec)
   write (*,22) sec-start, ' Completed '
!
 21 format (a,i0,' : ',f0.2,a,i0)
 22 format (f9.3,a,i0)
 23 format (f9.3,a,es10.2)
  end
!
  subroutine Elapse_Time (sec)
    real*8    sec
    integer*8 clock, rate
!
    call System_Clock ( clock, rate )
    sec = dble (clock) / dble (rate)
  end subroutine Elapse_Time
!
  subroutine Delta_Time (dt)
    real*8 :: dt, sec
    real*8 :: last = 0
!
    call Elapse_Time (sec)
    dt   = sec - last
    last = sec
  end subroutine Delta_Time

我在 3 台电脑上测试了此代码,其中 2 台使用 SSD。 i5 有 Win 7 8Gb 内存,而 i7 有 Win 10 32Gb 内存。下表列出了我获得的性能。文件大小约为 85% 的内存,因此磁盘缓冲不应该很重要。结果可能是可变的。 SSD 性能低于预期让我感到惊讶,而 i7 HDD 性能却好于预期?

Disk           File Gb write sec  read sec write Mb/s  read Mb/s
i5-2300  C:HDD     4.6      42.1      58.9      108.3       77.5
i7-4790K E:HDD    26.9     175.0     168.7      153.8      159.6
i7-4790K C:SSD    26.9     154.7     106.4      174.0      252.9
i7-8700K E:HDD    26.9     141.8     132.7      189.8      202.8
i7-8700K C:SSD    26.9     116.9      97.5      230.2      276.0

我希望这些结果能够说明串行流 I/O 可以实现什么。不确定在这些情况下预期的 MPI I/O 速率是多少?

【讨论】:

  • 顺序内存访问对于大型数组很重要,可以在此示例中进行演示。你应该检查 "(( p(ibk,jbk), ibk=1,nsea), jbk=1,nsea)" 与 "(( p(ibk,jbk), jbk=1,nsea), ibk=1,nsea )”。 FORALL 的顺序取决于编译器。
  • 非常感谢约翰坎贝尔。会回复你的
猜你喜欢
  • 2013-09-09
  • 1970-01-01
  • 1970-01-01
  • 2014-06-16
  • 2021-12-08
  • 1970-01-01
  • 2017-01-17
  • 1970-01-01
  • 2012-04-29
相关资源
最近更新 更多