Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!

Derived data type memory access

Gordey_G_
Beginner
72 Views

Hello everyone!

We have found strange behaviour of the following simple program that implements jacobi-like iteration with array of derived data type (block_t). This type consists of one-dimensional allocatable array. Pointer introduction (p1, p2) leads to the decrease in execution time from 3.2 seconds to 1.54 seconds on  Intel(R) Xeon(R) CPU X5355 @ 2.66GHz and compiler ifort 15.0.2 20150121 with -O3 option. Also we checked it on Intel i3-3220 3.3GHz and compiler ifort 18.0.0 20170811. It is remarkable that without if-condition in the loops, execution time becomes actually the same and equals 0.92 seconds.

Can anybody explain such a behaviour?

Thank you in advance.

Gordey.

program main
  implicit none
  
  type :: block_t
    real(kind=8), allocatable :: b(:)
  end type block_t
  
  type(block_t), allocatable, target :: var1(:), var2(:)
  real(kind=8), pointer, contiguous :: p1(:), p2(:)
  logical(kind=1), allocatable :: mask(:)
   
  integer(kind=4) :: nx, nb, nit
  integer(kind=4) :: i , ib, ni
  real   (kind=8) :: ts, te
  
  nx = 1000
  nit = 1000000
  nb = 1
  
  allocate(var1(nb),var2(nb))
  allocate(var1(nb).b(0:nx+1),var2(nb).b(0:nx+1))
  allocate(mask(0:nx+1))
  
  var1(1).b = 1
  var2(1).b = 2
  mask = .true.
  
  call CPU_time(ts)
  do ni = 1, nit
    do ib = 1, nb
      do i = 1, nx
	if (mask(i)) then
	  var2(ib).b(i) = 0.5_8 * (var1(ib).b(i+1) + var1(ib).b(i-1))
	end if
      end do
      var1(ib).b = var2(ib).b
    end do
  end do
  call CPU_time(te)
  print*, 'no pointer time', te - ts
  
  call CPU_time(ts)
  do ni = 1, nit
    do ib = 1, nb
      p1 => var1(ib).b
      p2 => var2(ib).b
      do i = 1, nx
	if (mask(i)) then
	  p2(i) = 0.5_8 * (p1(i+1) + p1(i-1))
	end if
      end do
      var1(ib).b = var2(ib).b
    end do
  end do
  call CPU_time(te)
  print*, 'pointer time', te - ts
  
end program main

 

0 Kudos
0 Replies
Reply