Нет ускорения с OpenMP при использовании Matlab MEX в Linux - PullRequest
1 голос
/ 27 мая 2020

Я использую OpenMP для ускорения кода Fortran в MEX-файле Matlab. Однако я обнаружил, что OpenMP не работает на Linux, но на самом деле работает на Windows. Я прикрепляю код следующим образом:

1) Файл Matlab Mex:

clc; clear all; close all;   tic

FLAG_SYS = 0; % 0 for Windows; 1 for Linux

%--------------------------------------------------------------------------
% Mex Fortran code 
%--------------------------------------------------------------------------
if FLAG_SYS == 0
    mex COMPFLAGS="-Qopenmp $COMPFLAGS"...
        LINKFLAGS="/Qopenmp $LINKFLAGS"...   
        OPTIMFLAGS="/Qopenmp $OPTIMFLAGS"...
        '-IC:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2017.5.267\windows\mkl\include'...
        '-LC:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2017.5.267\windows\mkl\lib\intel64'...
        -lmkl_intel_ilp64.lib -lmkl_intel_thread.lib -lmkl_core.lib libiomp5md.lib...
        Test_OpenMP_Mex.f90...
        -output Test_OpenMP_Mex  

elseif FLAG_SYS == 1        
    mex COMPFLAGS="-fopenmp $COMPFLAGS"...
        LINKFLAGS="-fopenmp $LINKFLAGS"...  
        FFLAGS='$FFLAGS -fdec-math -cpp' ...
        '-I${MKLROOT}/include'...
        '-L${MKLROOT}/lib'...
        -lmkl_avx2 -lmkl_gf_ilp64 -lmkl_core -lmkl_intel_thread -liomp5 -lpthread -lm -ldl...
        Test_OpenMP_Mex.f90...
        -output Test_OpenMP_Mex           
end

Test_OpenMP_Mex;

2) Код Fortran

#include "fintrf.h"

     !GATEWAY ROUTINE
      SUBROUTINE MEXFUNCTION(NLHS, PLHS, NRHS, PRHS)

     !DECLARATIONS
      IMPLICIT NONE

     !MEXFUNCTION ARGUMENTS:
      MWPOINTER PLHS(*), PRHS(*)
      INTEGER NLHS, NRHS

     !FUNCTION DECLARATIONS:
      MWPOINTER MXCREATEDOUBLEMATRIX

      MWPOINTER MXGETM, MXGETN
      INTEGER MXISNUMERIC 

     !POINTERS TO INPUT MXARRAYS:
      MWPOINTER MIV1, MIV2

     !POINTERS TO OUTPUT MXARRAYS:
      MWPOINTER MOV1, MOV2

     !CALL FORTRAN CODE
     CALL  TEST_OPENMP


      RETURN

      END

!-----------------------------------------------------------------------
    SUBROUTINE TEST_OPENMP

        USE OMP_LIB

        IMPLICIT NONE

        INTEGER I, J, K, STEP
        REAL*8  STARTTIME, ENDTIME,Y


        OPEN(1,FILE='1.TXT') 

        !COUNT ELAPSED TIME START
        STARTTIME = OMP_GET_WTIME() 

        DO I = 1,1000000
            DO J = 1,50000
                DO K = 1,1000
                    Y=(I+10)*J-SQRT(789.1)+SQRT(789.1)-(I+10)*J
                END DO
            END DO
        END DO     


        ENDTIME = OMP_GET_WTIME()
        WRITE(1,*) ENDTIME-STARTTIME

        !COUNT ELAPSED TIME START
        STARTTIME = OMP_GET_WTIME() 

!$OMP PARALLEL
!$OMP DO PRIVATE(I,J)
        DO I = 1,1000000
            DO J = 1,50000
                DO K = 1,1000
                    Y=(I+10)*J-SQRT(789.1)+SQRT(789.1)-(I+10)*J
                END DO
            END DO
        END DO     
!$OMP END DO  
!$OMP END PARALLEL        

        ENDTIME = OMP_GET_WTIME()
        WRITE(1,*) ENDTIME-STARTTIME 

!$OMP PARALLEL        
        ! GET THE NUMBER OF THREADS
        WRITE(1,*) OMP_GET_THREAD_NUM(), OMP_GET_NUM_THREADS() 
!$OMP END PARALLEL         
        CLOSE(1)

        RETURN

      END SUBROUTINE TEST_OPENMP

Вывод на Windows:

   1.09620520001044     
   4.50355500000296     
   0           6
   1           6
   3           6
   5           6
   2           6
   4           6

, а вывод на Linux:

   0.0000   
   0.0000    
   0           1

Очевидно, что OpenMP работает на Windows, поскольку время расчета сокращается с 4,5 до 1,0 с. Я обнаружил, что для расчета используется 6 потоков. Однако на Linux вычисления, похоже, не выполняются, и есть только 2 потока (количество потоков на Linux равно 36, но используются только 2 из них).

Любые предложения добро пожаловать!

Вы можете напрямую загрузить код по этой ссылке: https://www.dropbox.com/sh/crkuwhu22407sjs/AAAQrtzAvTmFOmAxv_jpTCBaa?dl=0

Ответы [ 2 ]

3 голосов
/ 27 мая 2020

При компиляции MEX-файлов под Linux (и MacOS) переменная COMPFLAGS игнорируется. Это переменная среды Windows -specifi c. Вам нужно использовать CFLAGS для C, CXXFLAGS для C ++ или FFLAGS для Fortran и LDFLAGS для компоновщика. Это стандартные Unix переменные среды для управления компиляцией.

Ваша команда компиляции будет выглядеть так:

mex LDFLAGS='-fopenmp $LDFLAGS'...
    FFLAGS='-fopenmp -fdec-math -cpp $FFLAGS' ...
    '-I${MKLROOT}/include'...
    '-L${MKLROOT}/lib'...
    -lmkl_avx2 -lmkl_gf_ilp64 -lmkl_core -lmkl_intel_thread -liomp5 -lpthread -lm -ldl...
    Test_OpenMP_Mex.f90...
    -output Test_OpenMP_Mex

Ссылка:

1 голос
/ 28 мая 2020

Есть одно замечание, которое вы не должны пропустить, сравнивая версии библиотек Intel mkl ilp64: вам нужно добавить параметр компилятора -I4, иначе вы можете увидеть какой-то неожиданный segfault ... Пожалуйста, обратитесь к mkl советник компоновщика, чтобы узнать больше: https://software.intel.com/content/www/us/en/develop/articles/intel-mkl-link-line-advisor.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...