在更好的优化标志和OpenMP之后,向量的计算变得更慢。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在更好的优化标志和OpenMP之后,向量的计算变得更慢。相关的知识,希望对你有一定的参考价值。

考虑以下Fortran代码

program example
    implicit none
    integer, parameter  ::  ik = selected_int_kind(15)
    integer, parameter  ::  rk = selected_real_kind(15,307)

    integer(ik)         :: N, i, j, pc, time_rate, start_time, end_time, M

    real(rk), allocatable:: K(:,:), desc(:,:)
    real(rk)                :: kij, dij

    integer             :: omp_get_num_threads, nth
    N = 2000
    M = 400

    allocate(K(N,N))
    allocate(desc(N,M))

    pc=10
    do i = 1, N
        desc(i,:) = real(i,rk)
        if (i==int(N*pc)/100) then
            print * ,"desc % complete: ",pc
            pc=pc+10
        endif
    enddo
    call system_clock(start_time)
    !$OMP PARALLEL PRIVATE(nth)
    nth = omp_get_num_threads()
    print *,"omp threads", nth
    !$OMP END PARALLEL

    !$OMP PARALLEL DO &
    !$OMP DEFAULT(SHARED) &
    !$OMP PRIVATE(i,j,dij,kij)
    do i = 1, N
        do j = i, N
            dij = sum(abs(desc(i,:) - desc(j,:)))
            kij = dexp(-dij)
            K(i,j) = kij
            K(j,i) = kij
        enddo
        K(i,i) = K(i,i) + 0.1
    enddo
    !$OMP END PARALLEL DO

    call system_clock(end_time, time_rate)
    print* , "Time taken for Matrix:", real(end_time - start_time, rk)/real(time_rate, rk)

end program example

我在MacOS X 10.11上使用gfortran-6编译了它,使用了以下标志

  1. gfortran example.f90 -fopenmp -O0
  2. gfortran example.f90 -fopenmp -O3
  3. gfortran example.f90 -fopenmp -mtune=native

下面我使用OMP_NUM_THREADS变量用单线程和双线程运行它。我可以看到它利用了两个核心。然而,应该启用矢量化的O3标志对性能没有任何帮助,甚至还降低了一点。下面给出了时间(以秒为单位)(10次运行的平均值)。

|Thrds->|   1  |  2  |
|Opt    |      |     |
----------------------
|O0     |10.962|9.183|
|O3     |11.581|9.250|
|mtune  |11.211|9.084|

我的程序有什么问题?

答案

首先,如果你想从这里获得良好的性能,就必须从 -O3你应该给它一些可以实际优化的东西。大部分的工作发生在 sum 内在的,它的工作原理是向量化表达式。当你从 -O0-O3.

另外,如果你想获得更好的性能,可以将其转置为 desc 因为 desc(i,:) 是记忆中的非连续。desc(:,i) 是。这就是Fortran--它的矩阵是列主型的。

以上是关于在更好的优化标志和OpenMP之后,向量的计算变得更慢。的主要内容,如果未能解决你的问题,请参考以下文章

OpenMP:使用较少的长线程更好,还是使用最大可用的短线程更好?

共享内存的 MPI 与 openMP

如何在 CMake 的 try_compile 函数中为 OpenMP 设置链接器标志

OpenMP 中的同步

OpenMP和不同的STL向量

在混合 MPI/OpenMP 中进行 MPI 调用的线程