Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

multiplication

GHui
Novice
1,020 Views
Is there any way to speed up the following code?



[fortran]do i=1,1000000 s0=i*10+1 s1=i*10+10 do j=s0,s1 val(i) = val(i) + a(j)*c(j) enddo enddo[/fortran]





0 Kudos
6 Replies
TimP
Honored Contributor III
1,020 Views
It may help to replace the inner loop by
!dir$ unroll(0)
val(i)=val(i)+dot_product(a(so:s1),c(s0:s1))

ifort should optimize this with default options. -assume protect_parens will not prevent this optiimation, but -fp-model source et al. will inhibit "vectorization."
Alternative to portable dot_product is intel-specific !dir$ simd reduction.
As your loop length is only 10, you dont't get full benefit of compiler vectorization when you can't specify data alignment. Compiler may say "seems inefficient" when it sees loop length 10 with unknown alignment.
Other traditional possibilites include writing it out in various non-sequential forms:
val(i)=val(i)+dot_product(a(s0:s0+1),c(so:s0+1)+dot_product(a(s0+2:s0+9),c(s0+2:s0+9)) .....
this also may depend strongly on alignment if any vectorization is involved.
Ideally, the compiler would not invoke alignment dependence when you use an option such as -xHost which should take advantage of current instruction sets.
0 Kudos
GHui
Novice
1,020 Views
[#]$ ifort loop.f90
loop.f90(7): warning #7866: The statement following this DEC loop optimization directive must be an iterative do-stmt, a vector assignment, an OMP pdo-directive, or an OMP parallel-do-directive.
!dir$ unroll(0)
------^

Is there anything I make mistake?
0 Kudos
SergeyKostrov
Valued Contributor II
1,020 Views
Quoting GHui
Is there any way to speed up the following code?...

...
do i = 1, 1000000
s0 = i * 10 + 1
s1 = s0 + 9
do j = s0, s1
val(i) = val(i) + a(j) * c(j)
enddo
enddo
...
0 Kudos
TimP
Honored Contributor III
1,020 Views
Sorry, apparently you will need to omit the unroll directive when trying dot_product.
0 Kudos
GHui
Novice
1,020 Views
I try dot_product for several cases. There isn't better performance.
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,020 Views
  1. doi=1,1000000
  2. s0=i*10+1
  3. s1=i*10+10
  4. doj=s0,s1
First iteration does 11:20, second does 21:30, ...

Shouldn't your i loop be
doi=0,1000000?
(or i loop control reduced by /10?)

Also, are val(:), a(:) and c(:) dimensioned at 1000000*10+10?
IOW 10x the size of the i loop iteration plus 10


Try creating temp array of proper size (same as size for val(:), a(:) and c(:))

! the following will vectorize quite well
! do the product part of the dot products
do i=1,1000000*10+10
temp(i) = a(i) * c(i)
end do
! now do the sum part of the small dot products
do i=1,1000000
s0=i*10+1
s1=i*10+10
t = 0.0
do j=s0,s1
t = t + temp(j)
end do
val(i) = val(i) + t
end do

Start with that

Jim Dempsey
0 Kudos
Reply