C 基于OpenMP的泰勒级数
ex=1+x+x2/2!+x3/3!+x4/4!+x5/5!+ 我已经把一个泰勒级数的ex(上面)转换成一个OpenMp程序。 所有代码都写在下面 当我通过OracleUbuntu运行代码时,它工作正常。 它给了我C 基于OpenMP的泰勒级数,c,openmp,C,Openmp,ex=1+x+x2/2!+x3/3!+x4/4!+x5/5!+ 我已经把一个泰勒级数的ex(上面)转换成一个OpenMp程序。 所有代码都写在下面 当我通过OracleUbuntu运行代码时,它工作正常。 它给了我e^0=1,e^1=2.718,e^2=7.389056 但是当我在Ubuntu上运行它时(不是虚拟的),它就不能正常工作了。 它给了我e^0=nan,e^1=0.40..,e^2=4.780 输出是完全随机的,因为它不像我上面提到的那样精确。 我需要帮助 #include <
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);
}
#包括
#包括
#包括
长双x,事实[150],压水堆[150],s[1];
int i,术语;
无效*功率(无效*温度){
int k;
对于(k=0;k<150;k++){
压水堆[k]=功率(x,k);
//printf(“%.2Lf\n”,压水堆[k]);
}
返回压水堆;
}
无效*事实(无效*临时){
长双f;
int j;
事实[0]=1.0;
用于(术语=1;术语<150;术语++){
f=1.0;
对于(j=项;j>0;j--)
f=f*j;
事实[术语]=f;
//printf(“%.2Lf\n”,事实[术语]);
}
返回事实;
}
void*Exp(void*temp){
int t;
s[0]=0;
对于(t=0;t<150;t++)
s[0]=s[0]+(pwr[t]/fact[t]);
返回s;
}
内部主(空){
pthread_t thread1、thread2、thread3;
长双倍**和;
printf(“指数[提示]输入x的值(0到100之间)(用于计算exp(x)):”;
扫描频率(“%Lf”、&x);
printf(“\nExponential[INFO]线程创建…\n”);
pthread_create(&thread1,NULL,Power,NULL);//调用Power函数
pthread_create(&thread2,NULL,Fact,NULL);//调用阶乘函数
printf(“创建的指数[INFO]线程\n”);
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
printf(“指数[INFO]主线程和终止线程正在连接\n”);
printf(“主线程中收集的指数[INFO]结果\n”);
pthread_create(&thread3,NULL,Exp,NULL);
pthread_join(thread3,sum);
printf(“\n exp(%.2Lf)的初始[INFO]值为:%Lf\n\n”,x,s[0]);
出口(1);
}
上面的代码最初用于使用线程的ex,它可以工作
#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);
}
#包括
#包括
#包括
#包括
内部主(空){
长双x,f,fact[150],pwr[150],s[1];
int i,term,k,j,t;
长双和;
printf(“指数[提示]输入x的值(0到100之间)(用于计算exp(x)):”;
扫描频率(“%Lf”、&x);
#pragma omp并行num_线程(10个)
#pragma omp for
对于(k=0;k<150;k++){
对于(inth=0;h0;j--)
f=f*j;
事实[术语]=f;
}
#pragma omp for
对于(t=0;t<150;t++)
s[0]=s[0]+(pwr[t]/fact[t]);
printf(“\n exp(%.2Lf)的初始[INFO]值为:%Lf\n\n”,x,s[0]);
出口(1);
}
上面的代码是以前代码到OpenMP的转换。for(t=0;t<150;t++)
for (t = 0; t < 150; t++)
s[0] = s[0] + (pwr[t] / fact[t]);
s[0]=s[0]+(pwr[t]/fact[t]);
此代码在并行化时,将与部分计算结果同时覆盖同一变量。这只有在线程以某种方式协调时才能起作用。幸运的是,openmp有一个专门的指令reduce
,用于计算总和,因此您可以很容易地解决这个问题
在
pthread
版本的代码中,一个线程执行此计算,因此没有问题。Post a。特别是,我想知道您尝试了哪些输入,您运行此操作的任何系统都会给出正确的结果。我不明白为什么在第一个循环中将全局x
重置为1。这将导致错误的结果。线程错误地更新了几个全局变量:f
和s[0]
。对于第二种情况,您应该使用reduce。对于f
使用一个线程局部变量。在第二个#pragma omp For
之前缺少一个}
,我很好奇地看到在处理这段代码时花费了这么多精力,这不会降低其内在复杂性,这些项可以以线性成本递增计算,而不是使用pow
函数和嵌套循环。您希望omp
并行计算什么?前两个for
循环可以在单独的线程中计算,但最后一个for
循环需要前面两个循环的结果,因此不能与前面两个循环并行启动。它必须首先等待两者完成。