Skip to content

Latest commit

 

History

History

PWR025

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

PWR025: Consider annotating pure function with OpenMP declare simd

Issue

A SIMD version of the function can most likely be generated by the compiler.

Actions

Annotate the pure function with #pragma omp declare simd.

Relevance

A loop invoking functions tends to make it difficult for the compiler to vectorize. However, calls to some functions can be vectorized. Calls to a pure function (function whose return value depends only on function arguments) can be vectorized if the compiler is instructed to do so with a compiler pragma.

Note

If the compiler manages to inline the function, then vectorization pragma is not needed. To see the performance benefit of this approach, the caller loop and called functions must reside in different compilation units.

Also, make sure OpenMP support in your compiler is enabled using compiler switches (typically -fopenmp-simd or -fopenmp).

Code example

C

The following loop invokes a pure function foo:

__attribute__((const)) int foo(int a) {
  return 2 * a;
}

void example(int *A, int n) {
  for (int i = 0; i < n; i++) {
    A[i] = foo(i);
  }
}

By adding the #pragma omp declare simd clause, the compiler will create a vectorizable version of foo:

#pragma omp declare simd
__attribute__((const)) int foo(int a) {
  return 2 * a;
}

void example(int *A, int n) {
  for (int i = 0; i < n; i++) {
    A[i] = foo(i);
  }
}

Fortran

The following loop invokes a pure function foo:

subroutine example(A)
  implicit none
  integer, intent(out) :: A(:)
  integer :: i

  do i = 1, size(A, 1)
    A(i) = foo(i)
  end do

contains

  pure integer function foo(a)
    implicit none
    integer, intent(in) :: a
    foo = 2 * a
  end function foo
end subroutine example

By adding the !$omp declare simd clause, the compiler will create a vectorizable version of foo:

subroutine example(A)
  implicit none
  integer, intent(out) :: A(:)
  integer :: i

  do i = 1, size(A, 1)
    A(i) = foo(i)
  end do

contains

  pure integer function foo(a)
    !$omp declare simd
    implicit none
    integer, intent(in) :: a
    foo = 2 * a
  end function foo
end subroutine example

References