eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programmingOpenMP - jest szybciej czy wolniej?Re: OpenMP - jest szybciej czy wolniej?
  • Data: 2012-03-05 15:14:06
    Temat: Re: OpenMP - jest szybciej czy wolniej?
    Od: " M.M." <m...@N...gazeta.pl> szukaj wiadomości tego autora
    [ pokaż wszystkie nagłówki ]

    Roman W <b...@g...pl> napisał(a):

    > Mialem na mysli np. cos takiego:
    [ciach]
    > Nawet dla parametrow przy ktorych program dziala tylko kilkanascie sekund (=
    > array-size =3D 1000000) 2 watki wykonuja sie znacznie szybciej niz 1, a 4 t=
    > o juz ho-ho.

    Czyli stawiasz teze ze watki z boosta sa szybsze niz z OpenMP.
    Nie mam wprawy w poslugiwaniu sie watkami boostowymi, na kolanie nie
    napisze i nie sprawdze. Waskim gardlem w tworzeniu watkow jest wywolanie
    systemowe i byc moze wykonanie specyficznych instrukcji procesora
    plus przerzucanie/konflikty cache - zaleznie jak to jest zaimplementowane
    na danym modelu procesora. Takie problemy ma kazda biblioteka, kazda
    musi tworzyc watek za posrednictwem systemu. Mysle ze nie masz racji,
    mysle ze OpenMP jest bardzo podobna pod wzgledem wydajnosci jak
    kazda inna dobra(!) biblioteka, czy inny standard.

    Zobacz ten program:
    http://pastebin.com/Kw6pREMG

    Uruchamiam go z parametrami:
    13 1000000 3000
    Czyli procedura wykonuje 1 milion petli i jest wywolywana 3tys
    razy. Czas sumaryczny na i3 (dwa fizyczne prcesory, cztery z hyperthreading)
    Dla 1 watku mam czas 13s.
    Dla 2 .............. 7s
    Dla 3 .............. 7s
    Dla 4 .............. 6s
    dla 20 .............. 7s

    Oznacza to ze na jedno utworzenie watku przypada 13s / 3000 ~= 4ms
    obliczen. A pomimo to OpenMP uzyskuje liniowe przyspieszenie. Nie widac
    zadnego narzutu na tworzenie watkow. Nie mam pojecia i nie chce miec
    pojecia (bo do czego mi to potrzebne?) czy OpenMP raz utworzylo watki i
    sprytnie im przydziela zadania, czy moze tworzy je za kazdym razem od nowa
    gdy to jest potrzebne. Po prostu cala ta robote zrobil za mnie kompilator i
    OpenMP, ja raptem dopisalem jedna jedyna linijke kodu i mam ponad dwukrotne
    przyspieszenie na czasie obliczen 4 ms.

    Eksperymentowalem dalej, dodalem schedlule(static,1), czyli kazdy watek
    bierze po JEDNEJ! petli.
    #pragma omp parallel for reduction(+:res) schedule(static,1)
    Jaki czas? Dla dwoch watkow na tym procesorze 11s, czyli pomimo ze jeden
    watek otrzymuje okolo 20 taktow procesora do wykonania, to nadal widac
    przyspieszenie.

    Gdy dalem chunk=20
    #pragma omp parallel for reduction(+:res) schedule(static,20)
    To mam czas 10s dla dwoch watkow.

    Czego mozna chciec wiecej? Wszystko wskazuje na to, ze OpenMP nawet nie
    tworzy watkow, ale umie je sprytnie przytrzymac i dac im zadania zgodnie
    z zaleceniami synchronizacji. No i do tego prostota, jeden wiersz aby
    uzyskac zrwonoleglenie. Poza tym OpenMP umie sie komunikowac z innymi
    programami uruchomionymi w systemi. Jesli inny proces przydzieli sobie np.
    6 watkow, a system dysponuje 8 procesorami, to aplikacja otrzyma
    tylko 2 watki - w aplikacjach obliczeniowych najczesciej wlasnie tak jest
    optymalnie.

    Ah, bym zapomnial, kompiluja to wszystkie popularne kompiltory C++ pod
    wszystkie popularne systemy, niektore tylko sa troszke do tylu i nie
    obsluguja najnowszej wersji. Pomysl ma potencjal, byc moze jeszcze inne
    jezyki niz C++ i Fortan go zaadoptuja (a moze juz zaadoptowaly, a ja nie wiem)

    Pozdrawiam



    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <ctime>
    #include <omp.h>

    typedef double T;

    T* Inits( const int table_size ) {
    T *table = new T[table_size];
    for( int i=0 ; i<table_size ; i++ )
    table[i] = (T)(rand()%1024 - rand()%1024);
    return table;
    }


    T Compute( T table[] , const int table_size ) {
    T res = 0;
    #pragma omp parallel for reduction(+:res)
    for( int i=0 ; i<table_size ; i++ ) {
    res += table[i];
    if( table[i] > +10 ) table[i] -= 1;
    else if( table[i] < -10 ) table[i] += 1;
    else if( i%2 ) table[i] -= 13;
    else table[i] += 14;
    }
    return res;
    }


    int main(int argc, char *argv[]) {
    srand( atoi(argv[1]) );
    const int table_size = atoi(argv[2]);
    const int iterations = atoi(argv[3]);
    T *table = Inits( table_size );
    const time_t start = time(NULL);
    T res = 0;

    omp_set_num_threads( 3 );

    for( int i=0 ; i<iterations ; i++ )
    res += Compute( table , table_size );


    printf("result = %lf\n" ,(double)res );
    printf("all time = %ds\n", (int)(time(NULL)-start) );

    delete[] table;
    return 0;
    }

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

Podziel się

Poleć ten post znajomemu poleć

Wydrukuj ten post drukuj


Następne wpisy z tego wątku

Najnowsze wątki z tej grupy


Najnowsze wątki

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: