Ряд Тейлора с использованием OpenMP - PullRequest
0 голосов
/ 10 апреля 2019

e x = 1 + x + x 2 / 2! + х 3 / 3! + х 4 / 4! + х 5 / 5! + ...

Я преобразовал ряд Тейлора e x (выше) в программу OpenMp. Все коды написаны ниже.

Когда я запускаю код через Oracle Ubuntu, он работает. Это дает мне e^0=1,e^1=2.718,e^2=7.389056

Но когда я запускаю его в Ubuntu (не виртуально), тогда он работает неправильно. Это дает мне e^0=nan,e^1=0.40..,e^2=4.780.

И вывод абсолютно случайный, как и не точно, как я уже говорил выше. Мне нужна помощь.

 #include <math.h>
 #include <pthread.h>
 #include <stdlib.h>

 long double x, fact[150], pwr[150], s[1];
 int i, term;

 void *Power(void *temp) {
    int k;
    for (k = 0; k < 150; k++) {
        pwr[k] = pow(x, k);
        //printf("%.2Lf\n", pwr[k]);
    }
    return pwr;
}

void *Fact(void *temp) {
    long double f;
    int j;
    fact[0] = 1.0;
    for (term = 1; term < 150; term++) {
        f = 1.0;
        for (j = term; j > 0; j--)
            f = f * j;
        fact[term] = f;
        //printf("%.2Lf\n", fact[term]);
    }
    return fact;
}

void *Exp(void *temp) {
    int t;
    s[0] = 0;
    for (t = 0; t < 150; t++)
        s[0] = s[0] + (pwr[t] / fact[t]);
    return s;
}

int main(void) {
    pthread_t thread1, thread2, thread3;
    long double **sum;
    printf("Exponential [PROMPT] Enter the value of x (between 0 to 100) (for calculating exp(x)):");
    scanf("%Lf", &x);
    printf("\nExponential [INFO] Threads creating.....\n");
    pthread_create(&thread1, NULL, Power, NULL); //calling power function
    pthread_create(&thread2, NULL, Fact, NULL); //calling factorial function
    printf("Exponential [INFO] Threads created\n");
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    printf("Exponential [INFO] Master thread and terminated threads are joining\n");
    printf("Exponential [INFO] Result collected in Master thread\n");
    pthread_create(&thread3, NULL, Exp, NULL);
    pthread_join(thread3, sum);
    printf("\neXPONENTIAL [INFO] Value of exp(%.2Lf) is : %Lf\n\n", x, s[0]);
    exit(1);
}

Приведенный выше код изначально предназначен для e x с использованием потоков, которые работают.

#include <math.h>
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    long double x, f, fact[150], pwr[150], s[1];
    int i, term, k, j, t;
    long double sum;

    printf("Exponential [PROMPT] Enter the value of x (between 0 to 100) (for calculating exp(x)):");
    scanf("%Lf", &x);
    #pragma omp parallel num_threads(10)
    #pragma omp for
    for (k = 0; k < 150; k++) {
        for (int h = 0; h <= k; h++) {
            if (h == 0)
                x = 1;
            else
                pwr[k] = pow(x, k);
        }
    #pragma omp for
        for (term = 1; term < 150; term++) {
            f = 1.0;
            for (j = term; j > 0; j--)
                f = f * j;
            fact[term] = f;
        }
    #pragma omp for
        for (t = 0; t < 150; t++)
            s[0] = s[0] + (pwr[t] / fact[t]);

        printf("\neXPONENTIAL [INFO] Value of exp(%.2Lf) is : %Lf\n\n", x, s[0]);
        exit(1);
    }

И приведенный выше код является преобразованием предыдущего кода в OpenMP.

1 Ответ

0 голосов
/ 11 апреля 2019
for (t = 0; t < 150; t++)
            s[0] = s[0] + (pwr[t] / fact[t]);

Этот код при распараллеливании будет перезаписывать одну и ту же переменную одновременно с частичными результатами вычислений.Это может работать только тогда, когда потоки как-то скоординированы.К счастью, openmp имеет специальную директиву reduce для вычисления сумм, поэтому вы можете легко это исправить.

В версии кода pthread один поток выполняет этот расчет, поэтому проблем нет.

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