Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[OpenMP] równoległe obliczenia

Ostatnio zmodyfikowano 2013-06-06 23:03
Autor Wiadomość
johnyjj2
Temat założony przez niniejszego użytkownika
[OpenMP] równoległe obliczenia
» 2013-06-03 22:46:15
Cześć,

usiłuję zrównoleglić prosty program przy użyciu OpenMP:

C/C++
#include "stdafx.h"
#include <omp.h>

static long num_steps = 100000;
double step;
void main()
{
    int i;
    double x, pi, sum = 0.0;
    step = 1.0 /( double ) num_steps;
    #pragma omp parallel for private(x) reduction(+:sum) schedule(static,1)
    for( i = 1; i <= num_steps; i++ )
    {
        x =( i - 0.5 ) * step;
        sum = sum + 4.0 /( 1.0 + x * x );
    }
    pi = step * sum;
   
    printf( "Policzono: ", pi );
    while( 1 )
    {
        if( 'n' == getchar() )
             break;
       
    }
}

Dodałem dyrektywę pragma omp, gdzie zmienną prywatną jest x, jednak pod koniec wykonania aplikacji widzę w konsoli tylko "Policzono: " i niczego więcej. Na czym polega błąd?

Pozdrawiam!
P-84780
DejaVu
» 2013-06-04 00:36:47
C/C++
printf( "Policzono: ", pi );
:)
C/C++
printf( "Policzono: %f\n", pi );
:D

» standard Cprintf
P-84788
johnyjj2
Temat założony przez niniejszego użytkownika
» 2013-06-05 19:51:56
Dzięki :)
chyba już byłem za bardzo zmęczony, jak pisałem ten kod :P

Chciałbym teraz wykorzystać inne metody zrównoleglenia. Mam taki kod:

C/C++
#include "stdafx.h"
#include <omp.h>

static long num_steps = 100000;
//double step;
void main()
{
    double x, sum;
    double step = 1.0 /( double ) num_steps;
    double pi;
    #pragma omp parallel private(x,sum, step)
    {
        int i;
        sum = 0.0;
       
        #pragma omp for schedule(static,1)
        for( i = 1; i <= num_steps; i++ )
        {
            x =( i - 0.5 ) * step;
            sum = sum + 4.0 /( 1.0 + x * x );
        }
        #pragma omp critical
        pi = step * sum;
    }
    printf( "Policzono: %f\n", pi );
    while( 1 ) { if( 'n' == getchar() ) break; }
}

Problem w tym, że ciągle dostaję informację, że step nie jest zainicjalizowny. Widzę jednak w debuggerze, że po wykonaniu linii "step = 1.0 /(double) num_steps;" wartość się zmienia na: step = 1.0000000000000001e-005. Co tym razem może być źle :) (dlaczego twierdzi, że step nie jest zainicjalizowany)?

Chciałbym wykorzystać kilka różnych metod do zrównoleglenia, np.
* program SPMD używając tylko parallel region, => to zrobiłem w pierwszym poście (dodałem "Yes (/openmp)" w "OpenMP support" w Visual Studio oraz wyświetla się prawidłowe przybliżenie pi)
* używając work sharing construct (jest ich więcej), => to próbuję zrobić teraz (na podstawie trzeciego przykładu z: http://en.wikipedia.org/wiki /OpenMP#Clauses_in_work-sharing_constructs_.28in_C.2FC.2B.2B.29)
* używając private, reduction oraz worksharing construct.

Pozdrawiam!
P-84988
johnyjj2
Temat założony przez niniejszego użytkownika
» 2013-06-06 21:04:22
Cześć,
trochę zmodyfikowałem kod i usunąłem 'step' z 'private':
private(x,sum)
Teraz aplikacja się kompiluje i wykonuje, jednak na końcu otrzymuję Policzono: 1.570801, czyli połowę wartości.
Na co powinienem zwrócić uwagę, aby wynik był prawidłowy? (Podejrzewam, że dalej w niewłaściwy sposób są uwzględnione zmienne prywatne dla wątku i publiczne dla programu).
Pozdrawiam!
P-85077
DejaVu
» 2013-06-06 21:16:31
C/C++
long sum = 0, loc_sum;
/*forks off the threads and starts the work-sharing construct*/
#pragma omp parallel private(w,loc_sum)
{
    loc_sum = 0;
    #pragma omp for schedule(static,1)
    for( i = 0; i < N; i++ )
    {
        w = i * i;
        loc_sum = loc_sum + w * a[ i ];
    }
    #pragma omp critical
    sum = sum + loc_sum;
}
printf( "\n %li", sum );
To jest kod ze strony, którą sam podałeś... trzeba popatrzeć czy są jakieś różnice - albo przeczytać jakiś kurs.

/edit:
C/C++
pi = step * sum;
Powyższa linijka lipnie wygląda.
P-85079
DejaVu
» 2013-06-06 23:03:42
A tak w ogóle to ja bym w pierwszej kolejności skoncentrował się na pisaniu prostych algorytmów do wyliczania czegokolwiek z użyciem obliczeń równoległych po to, aby zrozumieć jak coś działa i jak należy narzędzia używać. Obecnie nie wiesz nic tj. nie wiesz czy wykonujesz poprawnie obliczenia ani nie wiesz czy prawidłowo wykorzystałeś operacje do zrównoleglenia aplikacji.

/edit:
Dodam jeszcze, że w 99% nie opłaca się tworzyć algorytmów równoległych, bo i tak większość osób ma procesory dwurdzeniowe, więc maksymalnie możesz podwoić szybkość obliczeń, a nieumiejętnie pisząc aplikację możesz nawet ją spowolnić bardziej, niż gdyby był to algorytm sekwencyjny/jednowątkowy. No chyba, że czerpiesz z tego walory edukacyjne to jak najbardziej warto poznać tą stronę medalu :)
P-85087
« 1 »
  Strona 1 z 1