# Array Operations in Fortran

**URL:** <https://fortran-lang.discourse.group/t/array-operations-in-fortran/2829>\
**Category:** Help\
**Created:** [February 20, 2022, 12:39pm UTC](https://fortran-lang.discourse.group/t/array-operations-in-fortran/2829 "2022-02-20T12:39:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Euler-37](https://avatars.discourse-cdn.com/v4/letter/e/b19c9b/32.png) [@Euler-37](https://fortran-lang.discourse.group/u/Euler-37)\
**Post date:** [February 20, 2022, 12:39pm UTC](https://fortran-lang.discourse.group/t/array-operations-in-fortran/2829/1 "2022-02-20T12:39:41Z")

</div>

### code

```auto
#define OPER +
program main
    implicit none
    real(kind=8), dimension(:), allocatable :: matx1
    real(kind=8), dimension(:), allocatable :: maty1
    real(kind=8), dimension(:), allocatable :: matz1
    real(8)::spenttime
    integer::i,j
    integer,parameter::n=40000000
    integer(kind=8)::time1,time2,time_rate

    allocate (matx1(n))
    allocate (maty1(n))
    allocate (matz1(n))
    call random_number(matx1)
    call random_number(maty1)

    call system_clock(time1,time_rate)
    matz1 = matx1 OPER maty1
    call system_clock(time2,time_rate)
    spenttime=(time2-time1)/real(time_rate,8)
    write (*,*) "spenttime:",spenttime;
    write (*,*) "print :",matz1(1);

    call system_clock(time1,time_rate)
    do i=1,n
        matz1(i) = matx1(i) OPER maty1(i)
    end do
    call system_clock(time2,time_rate)
    spenttime=(time2-time1)/real(time_rate,8)
    write (*,*) "spenttime:",spenttime;
    write (*,*) "print :",matz1(1);

    call system_clock(time1,time_rate)
    matz1= add(matx1, maty1)
    call system_clock(time2,time_rate)
    spenttime=(time2-time1)/real(time_rate,8)
    write (*,*) "spenttime:",spenttime;
    write (*,*) "print :",matz1(1);

    deallocate (matx1)
    deallocate (maty1)
    deallocate (matz1)
contains
    elemental function add(a,b)result(c)
        real(kind=8), intent(in) :: a,b
        real(kind=8):: c
        c=a OPER b
    end function add
end program main

```

### result

```sh
> gfortran
spenttime: 0.17802660000000001
print : 0.96720229161006710
spenttime: 4.8475799999999999E-002
print : 0.96720229161006710
spenttime: 4.7800099999999998E-002
print : 0.96720229161006710
> ifort
 spenttime: 6.500000000000000E-002
 print : 0.492660442309517
 spenttime: 3.700000000000000E-002
 print : 0.492660442309517
 spenttime: 3.600000000000000E-002
 print : 0.492660442309517
> nvfortran
 spenttime: 0.1808910000000000
 print : 1.064990525239708
 spenttime: 4.8655100000000000E-002
 print : 1.064990525239708
 spenttime: 6.2480000000000001E-002
 print : 1.064990525239708

```

### flags

```sh
ifort.exe 3.f90 -O3 -Qxcore-avx2 -fpp 
nvfortran 3.f90 -O3 -mavx2 -cpp 
gfortran 3.f90 -O3 -march=native -mavx2 -cpp 

```

it is shown that `array OPER array` is slower than `do loop`. `OPER ={+,-,*,/,**}`, Is there some problems in my code?

---

<div class="post-metadata">

**Author:** ![awvwgk](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/awvwgk/32/154_2.png) [@awvwgk](https://fortran-lang.discourse.group/u/awvwgk)\
**Post date:** [February 20, 2022, 12:47pm UTC](https://fortran-lang.discourse.group/t/array-operations-in-fortran/2829/2 "2022-02-20T12:47:16Z")

</div>

Try to reorder your calculation, the first one will probably always be the slowest.

To avoid this, you should repeat your micro-benchmark a couple of times by adding a loop or similar to remove any artifacts you get in the first couple of runs.

---

<div class="post-metadata">

**Author:** ![Euler-37](https://avatars.discourse-cdn.com/v4/letter/e/b19c9b/32.png) [@Euler-37](https://fortran-lang.discourse.group/u/Euler-37)\
**Post date:** [February 20, 2022, 12:54pm UTC](https://fortran-lang.discourse.group/t/array-operations-in-fortran/2829/3 "2022-02-20T12:54:19Z")

</div>

Yes , you are right, when copy the first calculation twice, it is shown different time spent. And the first one is slowest. 😀

---

<div class="post-metadata">

**Author:** ![septc](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/septc/32/77_2.png) [@septc](https://fortran-lang.discourse.group/u/septc)\
**Post date:** [February 20, 2022, 12:55pm UTC](https://fortran-lang.discourse.group/t/array-operations-in-fortran/2829/4 "2022-02-20T12:55:07Z")

</div>

Or insert `matz1 = 0` right after the statement `call random_number(maty1)`

---

<div class="post-metadata">

**Author:** ![Euler-37](https://avatars.discourse-cdn.com/v4/letter/e/b19c9b/32.png) [@Euler-37](https://fortran-lang.discourse.group/u/Euler-37)\
**Post date:** [February 20, 2022, 1:04pm UTC](https://fortran-lang.discourse.group/t/array-operations-in-fortran/2829/5 "2022-02-20T13:04:51Z")

</div>

> [@septc](#):
>
> ` 0` right after the statement `call random_n`

Yes , It is useful , and time for first example is same as others. Thanks both of you.
