eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programmingOpenMP - jest szybciej czy wolniej?
Ilość wypowiedzi w tym wątku: 81

  • 31. Data: 2012-03-02 14:49:39
    Temat: Re: OpenMP - jest szybciej czy wolniej?
    Od: "slawek" <s...@h...pl>


    Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
    wiadomości grup dyskusyjnych:jiqijf$dvn$1...@i...gazeta.pl...
    > Przekształcenia pętli w 3.3 to nie to samo, co w 4.6. Powiedziałbym nawet,
    > że dzielą je lata świetlne.

    Zgoda - tj. nie dosłownie ly, raczej zwykłe years.


  • 32. Data: 2012-03-02 15:57:50
    Temat: Re: OpenMP - jest szybciej czy wolniej?
    Od: Edek Pienkowski <e...@g...com>

    Dnia Fri, 02 Mar 2012 15:48:14 +0100, slawek napisal:

    > Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
    > wiadomości grup dyskusyjnych:jiqi0e$dvn$1...@i...gazeta.pl...
    >>> Pogrupuj po 64 i spróbuj:
    >>>
    >>> schedule(dynamic, 64)
    >
    > Nie pomogło: ani dynamic, ani static. Ani 64, ani 1, ani 1000 .

    A 1/nthreads rozmiaru? Poza tym nie wiem, jaki jest model fortranu,
    jak są obsługiwane shared.

    A gdybyś ręcznie zrobił z tego dwie pętle:

    for i = 0 ; i < n; i+= 1000
    for j = i * 1000; j < i*1000 + 1000 && j < n; j++

    ...i zwrównoleglał na zewnętrznej z j private?

    >
    >> ... bo inaczej zostawiasz decyzje gcc i/lub openMP, a jednocześnie
    >> używasz:
    >>
    >> -floop-parallelize-all
    >
    > Sprawdzałem też z "gołym" wywołaniem gfortran bez jakichkolwiek opcji.

    Już się ktoś pytał: to na pewno ta pętla? Zmieniałeś jej rozmiar?

    Edek


  • 33. Data: 2012-03-02 16:00:44
    Temat: Re: OpenMP - jest szybciej czy wolniej?
    Od: Edek Pienkowski <e...@g...com>

    Dnia Fri, 02 Mar 2012 15:57:50 +0000, Edek Pienkowski napisal:

    > Dnia Fri, 02 Mar 2012 15:48:14 +0100, slawek napisal:
    >
    >> Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
    >> wiadomości grup dyskusyjnych:jiqi0e$dvn$1...@i...gazeta.pl...
    >>>> Pogrupuj po 64 i spróbuj:
    >>>>
    >>>> schedule(dynamic, 64)
    >>
    >> Nie pomogło: ani dynamic, ani static. Ani 64, ani 1, ani 1000 .
    >
    > A 1/nthreads rozmiaru? Poza tym nie wiem, jaki jest model fortranu,
    > jak są obsługiwane shared.
    >
    > A gdybyś ręcznie zrobił z tego dwie pętle:
    >
    > for i = 0 ; i < n; i+= 1000
    > for j = i * 1000; j < i*1000 + 1000 && j < n; j++

    j = i ; j < i+1000 && j < n ; j++

    Sorry za głupi błąd.

    Edek


  • 34. Data: 2012-03-02 16:24:02
    Temat: Re: OpenMP - jest szybciej czy wolniej?
    Od: "slawek" <s...@h...pl>


    Użytkownik "Paweł Kierski" <n...@p...net> napisał w wiadomości grup
    dyskusyjnych:jiqgak$2sv$...@i...gazeta.pl...
    > Zredukuj program do samej pętli zawierające b(i) = a(i)+a(i), puść
    > w obu wersjach. Jeśli wyeliminujesz _wszystko_ inne, a problem będzie
    > nadal, to można podejrzewać implementację OpenMP, system itp. Bez

    Wyniki, w sekundach, są takie jak niżej. Program taki jak jeszcze niżej.

    gfortran -Ofast test-omp.f95 CPU_TIME = 0.20312500
    gfortran test-omp.f95 CPU_TIME = 1.9062500
    gfortran -fopenmp test-omp.f95 CPU_TIME = 7.0000000
    gfortran -Ofast -fopenmp .... CPU_TIME = 1.0625000 - jeżeli
    wątki tworzy się tylko raz (tj. $omp parallel obejmuje CAŁY program)

    Co widać? Że fast-math jest szybka, a nawet bardzo szybka - daje "10-krotne
    przyspieszenie". Natomiast OpenMP
    sucks - wykonanie programu jest ponad 3 razy wolniejsze do "zwykłego" - i
    prawie aż 35 razy wolniejsze niż z fast-math!


    Jak mi się to przekłada? Prawdziwy program (nie test) działał przez około 10
    dni na 16 CPU. Fast math daje efekt
    jakby procesorów było 160. Natomiast z OpenMP liczyłoby się to około 1 rok.

    Nie chce mi się przekładać tego na C/C++, bo intensywnie (tzn. prawdziwy
    program) używa liczb zespolonych itd.
    Jednak ciekawe będzie sprawdzić, jak to wyjdzie w MSVC (wersje od
    Professional wzwyż mają OpenMP). Ewentualnie
    p...ć OpenMP i użyć API Windows (_beginthread() i okolice). Ewentualnie
    zrobić dobry użytek z GPU.



    !***************************************************
    ****************************************************
    ************************
    !
    ! Program test-omp - powinno skompilowac sie kazdym kompilatorem Fortranu 95
    !
    !***************************************************
    ****************************************************
    ************************

    module main


    ! stale matematyczne i fizyczne (CODATA 2006)

    real*8, parameter :: pi =
    3.14159265358979323846264338327950288419716939938D0 ! pi
    real*8, parameter :: epsilon0 =
    8.85418781762038985053656303171075026060837016660D-1
    2 ! przenikalnosc
    elektryczna prozni [F/m]
    real*8, parameter :: c = 299792458.0D0
    ! predkosc swiatla [m/s]

    integer :: n,m;

    ! I/O units

    integer :: input = 11 ! tekstowy wejsciowy plik z danymi
    integer :: output = 12 ! tekstowy wyjsciowy plik z danymi

    contains

    subroutine setup(vec)
    implicit none
    complex*16, intent(out) :: vec(:)
    integer :: i
    do i = 1,n
    vec(i) = pi*c*epsilon0;
    enddo
    end subroutine setup

    subroutine solve(v1,v2)
    implicit none
    complex*16, intent(in) :: v1(:)
    complex*16, intent(out) :: v2(:)
    integer :: i

    !$omp parallel
    !$omp do schedule(static,100)
    do i = 1,n
    v2(i) = v1(i)/c**2 + abs(epsilon0) + pi
    enddo
    !$omp end do
    !$omp end parallel
    end subroutine solve

    end module main

    program testomp

    use main
    implicit none

    real*4 stamp0 ! pomiar czasu - stempel 0
    real*4 stamp1 ! pomiar czasu - stemper 1

    integer, parameter :: nmax = 10000 ! takie duze tablice sa

    complex*16 :: vec(nmax,2)
    integer :: i1,i2,i,j
    complex*16 :: sum


    call cpu_time(stamp0)


    n = 1000
    m = 100000

    if(n.le.nmax) then
    i1 = 1
    i2 = 2

    call setup(vec(:,i1))
    do j = 1,m
    call solve(vec(:,i1),vec(:,i2))
    i1 = mod(i1,2) + 1
    i2 = mod(i2,2) + 1
    enddo
    else
    write(*,*) 'error: dimension(s)'
    endif


    call cpu_time(stamp1)
    write(*,*) 'CPU time = ', stamp1-stamp0

    sum = 0.D0
    do i = 1,n
    sum = sum + 1.D0/(1.D0+vec(i,i1)*vec(i,i1))
    enddo
    write(*,*) 'just for fun ', sum


    end program testomp

    !***************************************************
    ****************************************************
    ************************




  • 35. Data: 2012-03-02 16:27:00
    Temat: Re: OpenMP - jest szybciej czy wolniej?
    Od: "slawek" <s...@h...pl>


    Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
    wiadomości grup dyskusyjnych:jiqqlu$dvn$1...@i...gazeta.pl...
    > Już się ktoś pytał: to na pewno ta pętla? Zmieniałeś jej rozmiar?

    Wysłałem właśnie przykładowy program - są co prawda 4 pętle, ale chyba widać
    o co chodzi.

    !***************************************************
    ****************************************************
    ************************
    !
    ! Program test-omp
    !
    !***************************************************
    ****************************************************
    ************************

    module main


    ! stale matematyczne i fizyczne (CODATA 2006)

    real*8, parameter :: pi =
    3.14159265358979323846264338327950288419716939938D0 ! pi
    real*8, parameter :: epsilon0 =
    8.85418781762038985053656303171075026060837016660D-1
    2 ! przenikalnosc
    elektryczna prozni [F/m]
    real*8, parameter :: c = 299792458.0D0
    ! predkosc swiatla [m/s]

    integer :: n,m;

    ! I/O units

    integer :: input = 11 ! tekstowy wejsciowy plik z danymi
    integer :: output = 12 ! tekstowy wyjsciowy plik z danymi

    contains

    subroutine setup(vec)
    implicit none
    complex*16, intent(out) :: vec(:)
    integer :: i
    do i = 1,n
    vec(i) = pi*c*epsilon0;
    enddo
    end subroutine setup

    subroutine solve(v1,v2)
    implicit none
    complex*16, intent(in) :: v1(:)
    complex*16, intent(out) :: v2(:)
    integer :: i

    !$omp do schedule(static,1000)
    do i = 1,n
    v2(i) = v1(i)/c**2 + abs(epsilon0) + pi
    enddo
    !$omp end do
    end subroutine solve

    end module main

    program testomp

    use main
    implicit none

    real*4 stamp0 ! pomiar czasu - stempel 0
    real*4 stamp1 ! pomiar czasu - stemper 1

    integer, parameter :: nmax = 10000 ! takie duze tablice sa

    complex*16 :: vec(nmax,2)
    integer :: i1,i2,i,j
    complex*16 :: sum


    call cpu_time(stamp0)


    n = 1000
    m = 100000

    if(n.le.nmax) then
    !$omp parallel

    i1 = 1
    i2 = 2

    call setup(vec(:,i1))
    do j = 1,m
    call solve(vec(:,i1),vec(:,i2))
    i1 = mod(i1,2) + 1
    i2 = mod(i2,2) + 1
    enddo
    !$omp end parallel
    else
    write(*,*) 'error: dimension(s)'
    endif


    call cpu_time(stamp1)
    write(*,*) 'CPU time = ', stamp1-stamp0

    sum = 0.D0
    do i = 1,n
    sum = sum + 1.D0/(1.D0+vec(i,i1)*vec(i,i1))
    enddo
    write(*,*) 'just for fun ', sum


    end program testomp




  • 36. Data: 2012-03-02 16:40:09
    Temat: Re: OpenMP - jest szybciej czy wolniej?
    Od: Edek Pienkowski <e...@g...com>

    Dnia Fri, 02 Mar 2012 17:27:00 +0100, slawek napisal:

    > Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
    > wiadomości grup dyskusyjnych:jiqqlu$dvn$1...@i...gazeta.pl...
    >> Już się ktoś pytał: to na pewno ta pętla? Zmieniałeś jej rozmiar?


    >
    > subroutine solve(v1,v2)
    > implicit none complex*16, intent(in) :: v1(:) complex*16,
    > intent(out) :: v2(:)
    > integer :: i
    >
    > !$omp do schedule(static,1000)
    > do i = 1,n
    > v2(i) = v1(i)/c**2 + abs(epsilon0) + pi
    > enddo !$omp end do
    > end subroutine solve
    >
    > end module main
    >

    > !$omp parallel
    >
    > i1 = 1 i2 = 2
    >
    > call setup(vec(:,i1))
    > do j = 1,m
    > call solve(vec(:,i1),vec(:,i2))
    > i1 = mod(i1,2) + 1 i2 = mod(i2,2) + 1
    > enddo
    > !$omp end parallel else
    > write(*,*) 'error: dimension(s)'
    > endif

    Po co zrównoleglać dwa razy, wewnętrznie? W głównym programie to
    jeszcze może mieć sens, na potrzeby testu trochę bez sensu
    i możesz mieć różne konflikty na vec.

    Edek


  • 37. Data: 2012-03-02 16:45:38
    Temat: Re: OpenMP - jest szybciej czy wolniej?
    Od: Edek Pienkowski <e...@g...com>

    Dnia Fri, 02 Mar 2012 16:40:09 +0000, Edek Pienkowski napisal:


    > Po co zrównoleglać dwa razy, wewnętrznie? W głównym programie to jeszcze
    > może mieć sens, na potrzeby testu trochę bez sensu i możesz mieć różne
    > konflikty na vec.

    Ignoruj... zapomniałem, co robi paralell.


  • 38. Data: 2012-03-02 16:50:11
    Temat: Re: OpenMP - jest szybciej czy wolniej?
    Od: "slawek" <s...@h...pl>


    Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
    wiadomości grup dyskusyjnych:jiqt59$dvn$1...@i...gazeta.pl...
    > Po co zrównoleglać dwa razy, wewnętrznie? W głównym programie to
    > jeszcze może mieć sens, na potrzeby testu trochę bez sensu
    > i możesz mieć różne konflikty na vec.

    W wariancie pierwszym było parallel wstawione na samą pętlę. W drugim jest
    na cały program - czyli nie ma dwa razy - tylko w innym miejscu.

    Ponieważ pętla była w pętli - to wątki były tworzone/niszczone
    wielokrotnie - chciałem więc sprawdzić, co będzie, jak wątki (2 sztuki)
    utworzy się tylko raz.

    To że cała reszta też liczy się dwa razy - okazuje się mniejszym problemem,
    niż koszt zawątkowywania-i-odwątkowywania. Śmieszne, ale prawdziwe.


  • 39. Data: 2012-03-02 19:11:08
    Temat: Re: OpenMP - jest szybciej czy wolniej?
    Od: "slawek" <s...@h...pl>


    Użytkownik "slawek" <s...@h...pl> napisał w wiadomości grup
    dyskusyjnych:4f50f420$0$1231$6...@n...neostrada
    .pl...
    > Wyniki, w sekundach, są takie jak niżej. Program taki jak jeszcze niżej.
    >
    > gfortran -Ofast test-omp.f95 CPU_TIME = 0.20312500
    > gfortran test-omp.f95 CPU_TIME = 1.9062500
    > gfortran -fopenmp test-omp.f95 CPU_TIME = 7.0000000
    > gfortran -Ofast -fopenmp .... CPU_TIME = 1.0625000 - jeżeli
    > wątki tworzy się tylko raz (tj. $omp parallel obejmuje CAŁY program)

    Po przeniesieniu do C i kompilacji MSVC 2010 jest nieco lepiej - ale i tak w
    rebusie

    bez OpenMP jest np. 8 sekund
    z OpenMP jest 12 sekund

    (Program jest trochę inny, bo nie ma complex i pętle z większą ilością
    iteracji.)




    /***************************************************
    ****************************************************
    ************************
    !
    ! Program test-omp
    !
    ! /openmp
    !
    ****************************************************
    ****************************************************
    ***********************/

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    // stale matematyczne i fizyczne (CODATA 2006)

    const double pi = 3.14159265358979323846264338327950288419716939938;
    const double epsilon0 =
    8.85418781762038985053656303171075026060837016660E-1
    2; // przenikalnosc
    elektryczna prozni [F/m]
    const double c = 299792458.0;
    // predkosc swiatla [m/s]

    static int n, m;

    void setup(double vec[])
    {
    int i;
    for(i = 0; i < n; i++)
    vec[i] = pi*c*epsilon0;
    }

    void solve(double v1[], double v2[])
    {
    int i;

    #pragma omp parallel
    {

    #pragma omp for schedule(static,100)
    for(i = 0; i < n; i++)
    v2[i] = v1[i]/(c*c) + epsilon0 + pi;
    }
    }

    int main(void)
    {
    clock_t stamp0; // pomiar czasu - stempel 0
    clock_t stamp1; // pomiar czasu - stempel 1

    // takie duze tablice sa
    # define nmax 10000

    // problem - nie ma typu complex w MSVC - zamiast
    complex
    // będzie używany double :(
    double vec[2][nmax];
    int i1,i2,i,j;
    double sum;

    stamp0 = clock();

    n = 1000;
    m = 1000000;

    if(n < nmax)
    {
    i1 = 0;
    i2 = 1;

    setup(vec[i1]);
    for(j = 0; j < m; j++)
    {
    solve(vec[i1],vec[i2]);
    i1 = (i1+1) % 2;
    i2 = (i2+1) % 2;
    }
    }
    else
    puts("error: dimension(s)");

    stamp1 = clock();

    printf("CPU time = %lf\n", (double)(stamp1-stamp0)/CLOCKS_PER_SEC);

    sum = 0.;
    for(i = 0; i < n; i++)
    sum += 1./(1.+vec[i1][i]*vec[i1][i]);

    printf("just for fun %lf\n",sum);

    getchar();
    return 0;
    }


  • 40. Data: 2012-03-03 06:28:26
    Temat: Re: OpenMP - jest szybciej czy wolniej?
    Od: " " <f...@N...gazeta.pl>

    slawek <s...@h...pl> napisał(a):

    >
    > Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
    > wiadomości grup dyskusyjnych:jiqt59$dvn$1...@i...gazeta.pl...
    > > Po co zrównoleglać dwa razy, wewnętrznie? W głównym programie to
    > > jeszcze może mieć sens, na potrzeby testu trochę bez sensu
    > > i możesz mieć różne konflikty na vec.
    >
    > W wariancie pierwszym było parallel wstawione na samą pętlę. W drugim
    jest
    > na cały program - czyli nie ma dwa razy - tylko w innym miejscu.
    >
    > Ponieważ pętla była w pętli - to wątki były tworzone/niszczone
    > wielokrotnie - chciałem więc sprawdzić, co będzie, jak wątki (2 sztuki)
    > utworzy się tylko raz.
    >
    > To że cała reszta też liczy się dwa razy - okazuje się mniejszym
    problemem
    > ,
    > niż koszt zawątkowywania-i-odwątkowywania. Śmieszne, ale prawdziwe.
    >

    mz wiadomo a przynajmniej bezpieczniej jest zakladac ze koszt
    owatkowienia moze byc spory, mi nie podoba sie watkowa rozrzutnosc,
    - byc moze tak naprawde systemy mozna by robic zupelnie inaczej
    trzebaby kiedys przemyslec podstawy wielowątkowosci
    - tak naprawde zeby zobaczyc co sie dzieje trzebeby zobaczyc
    i umiec zrozumiec kod schedulera i okolic w kernelu - warto
    by to bylo po prostu obejrzec (zob watek jadro jadra)





    --
    Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/

strony : 1 ... 3 . [ 4 ] . 5 ... 9


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: