我要评分
获取效率
正确性
完整性
易理解

Supported Fortran Directives

BiSheng compiler supports some of the Fortran directives. These directives instruct the compiler to perform optimization.

!$mem prefetch

This directive instructs the compiler to load specific data from the main memory to the L1/L2 cache. The method of using this directive is as follows:

1
2
3
4
!$mem prefetch array1, array2, array2(i + 4) 
DO i=1,100 
    array1(i - 1) = array2(i - 1) + array2(i + 1) 
END DO

In addition, prefetch with the specified cache level and cyclic iteration advance is supported. The usage is as follows:

prefetch: variable indicates the prefetch variable, locality indicates the cache level (1, 2, and 3 indicate L1, L2, and L3 respectively, and 4 indicates HBM cache), and distance indicates the cyclic iteration advance.

!$mem prefetch(variable, locality, distance)

noprefetch:

!$mem noprefetch(variable)

1
2
3
4
5
!$mem prefetch(array1,4,5)
!$mem noprefetch(array2)
DO i=1,100 
    array1(i - 1) = array2(i - 1) + array2(i + 1) 
END DO

!dir$ ivdep

This directive instructs the compiler to ignore the memory dependency of an iterative loop and to perform vectorization. The method of using this directive is as follows:

1
2
3
4
!dir$ ivdep 
DO i=1, ub 
    array1(i) = array1(i) + array2(i) 
END DO

!$omp simd

This directive instructs the compiler to convert a loop to SIMD format. This is an OpenMP instruction that takes effect only after the -fopenmp option is specified. The method of using this directive is as follows:

1
2
3
4
!$omp simd 
DO i=1, ub 
    array1(i) = array1(i) + array2(i) 
END DO

This directive does not support any clause.

!dir$ vector always

This directive forces the compiler to perform loop vectorization by ignoring cost-based dependencies. This operation takes effect immediately on the following loop. This directive requires the keyword "always" and cannot contain the keyword "never". The method of using this directive is as follows:

1
2
3
4
!dir$ vector always 
DO i=1, ub 
    array3(i) = array1(i) - array2(i) 
END DO

!dir$ novector

This directive instructs the compiler not to perform loop vectorization, regardless of the optimization level. This operation takes effect immediately on the following loop. The method of using this directive is as follows:

1
2
3
4
!dir$ novector 
DO i=1, ub 
    array3(i) = array1(i) - array2(i) 
END DO

!dir$ inline

This directive instructs the compiler to perform inlining for functions, regardless of the optimization level. This operation takes effect immediately on the following loop. The method of using this directive is as follows:

1
2
3
4
5
6
7
!dir$ inline 
real function inline_func (num) 
    implicit none
    real :: num
    inline_func = num + 1234
    return
end function

!dir$ noinline

This directive instructs the compiler not to perform inlining for functions, regardless of the optimization level. This operation takes effect immediately on the following loop. The method of using this directive is as follows:

1
2
3
4
5
6
7
8
9
!dir$ noinline 
subroutine noinline_func (a, b) 
    integer, parameter :: m = 10
    integer :: a(m), b(m)
    integer :: i
    do i = 1, m
        b(i) = a(i) + 1
    end do 
end subroutine noinline_func

!dir$ unroll

This directive instructs the compiler to perform loop unrolling, regardless of the optimization level. This operation takes effect immediately on the following loop. There are three methods of using this directive:

1
2
3
4
!dir$ unroll -- Unroll all
DO i=1, ub 
    array3(i) = array1(i) - array2(i) 
END DO
1
2
3
4
!dir$ unroll (4) -- Unroll four times
DO i=1, ub 
    array3(i) = array1(i) - array2(i) 
END DO
1
2
3
4
!dir$ unroll = 2 -- Unroll twice
DO i=1, ub 
    array3(i) = array1(i) - array2(i) 
END DO

!dir$ nounroll

This directive instructs the compiler to block the loop unrolling operation, immediately acting on the following loop. The method of using this directive is as follows:

1
2
3
4
!dir$ nounroll
DO i=1, 100
    array1(i) = 5 
END DO