Fortran векторизовать журнал внутри цикла for - PullRequest
2 голосов
/ 11 апреля 2020

Вот минимальный рабочий код.

program test
    implicit none

    double precision:: c1,c2,rate
    integer::ci,cj,cr,cm,i
    integer,parameter::max_iter=10000000 !10^7

    c1=0.0d+0

    CALL system_clock(count_rate=cr)
    CALL system_clock(count_max=cm)
    rate = REAL(cr)

    CALL SYSTEM_CLOCK(ci)
    do i=1,max_iter
        c1=c1+log(DBLE(i))
    end do
    CALL SYSTEM_CLOCK(cj)
    WRITE(*,*) "system_clock : ",(cj - ci)/rate

    print*, c1
end program test

Когда я компилирую с gfortran -Ofast -march=core-avx2 -fopt-info-vec-optimized, для l oop с функцией log не получается векторизация. Я также пробовал с -O3, но результат не меняется.

Но если я напишу эквивалентный код C ++,

#include <iostream>
#include <chrono>
#include <cmath>
using namespace std;
using namespace std::chrono;

int main()
{
    double c1=0;
    const int max_iter=10000000; // 10^7

    auto start = high_resolution_clock::now();
    for(int i=1;i<=max_iter;i++)
    {
        c1 += log(i);
    }
    auto stop = high_resolution_clock::now();

    auto duration = duration_cast<milliseconds>(stop - start); 
    cout << duration.count() << " ms"<<'\n'; 

    printf("%0.15f\n",c1);

    return 0;
}

и скомпилирую его с g++ -Ofast -march=core-avx2 -fopt-info-vec-optimized, для oop становится векторизованным и работает почти в 10 раз быстрее.

Что я должен сделать, чтобы сделать вортран l oop векторизованным?

1 Ответ

3 голосов
/ 12 апреля 2020

Проблема с векторизованными циклами, включающими математические функции (например, log), заключается в том, что компилятору необходимо научить семантике векторизованных математических функций (и вы увидите, если вы посмотрите на вывод ассемблера, который вызывает версия Fortran «нормальная» скалярная функция (строка типа call log), тогда как ваша версия C ++ вызывает векторизованную версию (call _ZGVdN4v___log_finite)). Была проделана некоторая работа, чтобы заставить GFortran понять библиотеку векторной математики glib c ( libmve c), но я не уверен, каков текущий статус. См. Нить, начинающуюся с https://gcc.gnu.org/legacy-ml/gcc/2018-04/msg00062.html и продолжающуюся в июне 2018 года, начиная с https://gcc.gnu.org/legacy-ml/gcc/2018-06/msg00167.html для получения дополнительной информации.

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