使用OpenMP的泰勒级数

时间:2019-04-10 17:35:16

标签: c openmp

e x = 1 + x + x 2 / 2! + x 3 / 3! + x 4 / 4! + x 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 :(得分:0)

for (t = 0; t < 150; t++)
            s[0] = s[0] + (pwr[t] / fact[t]);

此代码并行化时,将与部分计算结果同时覆盖同一变量。这仅在线程以某种方式进行协调时才有效。幸运的是,openmp具有专用的指令reduce用于计算总和,因此您可以轻松地解决此问题。

在代码的pthread版本中,一个线程进行了此计算,因此在那里没有问题。