暗示做。与IO的显式循环 [英] Implied do. vs explicit loop with IO

查看:161
本文介绍了暗示做。与IO的显式循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我意识到这个问题已被问及 之前,但不是在IO。有什么理由相信:

I realize this question has been asked before, but not in the context of IO. Is there any reason to believe that:

!compiler can tell that it should write the whole array at once?
!but perhaps compiler allocates/frees temporary array?
write(UNIT) (/( arr(i), i=1,N )/)

会比以下任何更有效:

would be any more efficient than:

!compiler does lots of IO here?
do i=1,N
   write(UNIT) arr(i)
enddo


$

for a file which is opened as:

open(unit=UNIT,access='STREAM',file=fname,status='UNKNOWN')

这可能与编译器一起使用选项关闭缓冲写入以及...

There is a possibly that this will be used with compiler options to turn off buffered writing as well ...

推荐答案

正如@HighPerformanceMark所建议的,这是我设置的一个简单基准:

As suggested by @HighPerformanceMark, here's a simple benchmark I set up:

使用gfortran:

Using gfortran:

  program main
  implicit none
  include 'mpif.h'
  integer, parameter :: N = 1000000 
  integer :: unit = 22
  integer i
  real*8 arr(N)
  real*8 t1
  integer repeat
  external test1
  external test2
  external test3

  repeat=15

  call MPI_INIT(i)

  arr = 0
  call timeit(test1,repeat,arr,N,t1)
  print*,t1/repeat

  call timeit(test2,repeat,arr,N,t1)
  print*,t1/repeat

  call timeit(test3,repeat,arr,N,t1)
  print*,t1/repeat

  call MPI_Finalize(i)

  end

  subroutine timeit(sub,repeat,arr,size,time)
  include 'mpif.h'
  external sub
  integer repeat
  integer size
  real*8 time,t1
  real*8 arr(size)
  integer i
  time = 0
  do i=1,repeat
     open(unit=10,access='STREAM',file='test1',status='UNKNOWN')
     t1 = mpi_wtime()
     call sub(10,arr,size)
     time = time + (mpi_wtime()-t1)
     close(10)
  enddo

  return
  end

  subroutine test1(ou,a,N)
  integer N
  real*8 a(N)
  integer ou
  integer i
  do i=1,N
     write(ou),a(i)
  enddo
  return
  end

  subroutine test2(ou,a,N)
  integer N
  real*8 a(N)
  integer ou
  integer i
  write(ou),(a(i),i=1,N)
  return
  end

  subroutine test3(ou,a,N)
  integer N
  real*8 a(N)
  integer ou
  write(ou),a(1:N)
  return
  end

我的结果是(缓冲):

temp $ GFORTRAN_UNBUFFERED_ALL=1 mpirun -np 1 ./test
   6.2392100652058922     
   3.3046503861745200     
   9.76902325948079409E-002

(无缓冲):

(unbuffered):

temp $ GFORTRAN_UNBUFFERED_ALL=0 mpirun -np 1 ./test
  2.7789104779561362     
  0.15584923426310221     
  9.82964992523193415E-002

这篇关于暗示做。与IO的显式循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆