并行化辛普森&x27;使用pthreads和OpenMp的C中的s方法

并行化辛普森&x27;使用pthreads和OpenMp的C中的s方法,c,multithreading,parallel-processing,pthreads,openmp,C,Multithreading,Parallel Processing,Pthreads,Openmp,我对整个多处理和并行化的世界是相当陌生的。我目前正在研究一种算法来实现辛普森方法和辛普森3/8。我已经在C中以串行形式实现了该算法 我需要一些帮助来使用OpenMp和Pthreads并行化这两种算法。欢迎提出任何建议,并表示感谢 //Simpson.c #include <stdio.h> #include <stdlib.h> double function(double x) //función a la cual se le aplicará el método

我对整个多处理和并行化的世界是相当陌生的。我目前正在研究一种算法来实现辛普森方法和辛普森3/8。我已经在C中以串行形式实现了该算法

我需要一些帮助来使用OpenMp和Pthreads并行化这两种算法。欢迎提出任何建议,并表示感谢

//Simpson.c
#include <stdio.h>
#include <stdlib.h>

double function(double x) //función a la cual se le aplicará el método
{
  return 0.5*x;    
}

int main(int argc, char*argv[])
{
  double resultado = 0.0; //resultado de la integral tras aplicar el método de simpson
  double a = 0.0;  //límite inferior de la integral
  double b = 0.0;  //límite superior de la integral
  int n = 0; //cantidad de particiones entre los intervalos, tiene que ser un número par
  int i = 0; //variable para poder iterar sobre las diferentes particiones
  double h = 0.0; //variable para guardar el incremento que habrá entre cada valor de "x"
  double calc = 0.0; //variable intermedia para ir acumulando el resultado de evaluar las diferentes "x" en la función
  
  //variables para almacenar los diferentes valores de "x", es decir los límites inferiores y superiores y el valor intermedio de cada partición  
  double x0 = 0.0;
  double x1 = 0.0;
  double x2 = 0.0;  
    
  printf("Introduce el límite inferior: ");
  scanf("%lf", &a);
  printf("Introduce el límite superior: ");
  scanf("%lf", &b);
  printf("Introduce la cantidad de particiones (número par): ");
  scanf("%d", &n);  
    
  h = (b-a)/n; //se calcula el incremento para poder iterar sobre todas las particiones
    
      //Para el cálculo de la integral se utilizan xj, x(j+1) y x(j+2) en el subintervalo [xj, x(j+2)] para cada i = 1, 3, 5, ..., n
    
  for (i=0; i<=n; i+=2)
  {   
    x0 = a + h*i; //límite inferior
    calc += function(x0); //se evalua la x en la función
    
    x1 = a + h*(i+1); //valor intermedio
    calc += 4*function(x1);
      
    x2 = a + h*(i+2); //límite superior
    calc += function(x2);
      
    calc *= ((x2-x0)/6) ; //se vuelve a calcular el incremento entre nuestros límites, y se divide entre 6
      
    resultado += calc; //variable para ir acumulando los cálculos intermedios de cada "x"
  }
    
  printf("La aproximación a la integral es: %f \n", resultado);

}
//Simpson.c
#包括
#包括
双功能(双x)//función a la cual se le aplicaráel método
{
返回0.5*x;
}
int main(int argc,char*argv[])
{
double resultado=0.0;//resultado de la integral tras aplicar el método de simpson
双a=0.0;//límite次积分
双b=0.0;//límite superior de la integral
INT=0;
int i=0;//不同的变量
双h=0.0;//变量参数“x”的增量
双计算=0.0;//函数中不同“x”的评估结果的可变中间值
//变量在“x”的不同价值中,在“x”的不同价值中,在“x”的不同价值中,在“x”的不同价值中,在“x”的不同价值中,在“x”的不同价值中,在“x”的不同价值中,在“x”的不同价值中,在“x”的不同价值中,在“x”的不同价值中
双x0=0.0;
双x1=0.0;
双x2=0.0;
printf(“介绍el límite Subermal:”);
scanf(“%lf”、&a);
printf(“介绍el límite superior:”);
scanf(“%lf”、&b);
printf(“介绍参与者(número par):”;
scanf(“%d”和“&n”);
h=(b-a)/n;//计算每一个项目的增量
//第i段=1,3,5,…,n

对于(i=0;i我的第一个建议是从大量阅读共享内存范例及其问题开始。然后阅读Pthreads和OpenMP,然后再看看具体的OpenMP和Pthread并行化,以及它们如何处理共享内存范例的一些问题。如果您必须同时学习Pthreads和OpenMP,请参阅我的观点ion,如果我是你,我会先研究Pthread,然后再研究OpenMP。后者有助于解决使用前者编码的一些繁琐细节和陷阱

关于如何实现代码的并行化,我将尝试给您提供一个非常通用的(而不是非常详细的)公式,我将以您的第二个代码和OpenMP为例

如果您选择并行化一个算法,首先您需要查看代码中值得并行化的部分(即,并行化带来的加速比掩盖了并行化的开销)。因为这种分析是基本的,但是,对于像您这样的较小代码,很容易找到它,它通常是循环,例如:

for(i=1; i<= N-1; i++)
  {
    k = a + i*dx; //Suma del intervalo
    
    if(i%3 == 0)
    {
      resultado = resultado + 2 * f(k);
    }
    else
    {
      resultado = resultado + 3 * f(k);
    }
  }
在保证代码的正确性后,您可以查看负载不平衡问题(即每个线程执行的工作之间的差异)。为了解决此问题,openMP提供了类似于
动态
引导
的并行调度策略(另一个)以及调整这些分布的块大小的可能性

在您的代码中,线程将执行相同数量的并行工作,因此无需使用
动态
引导
计划,您可以选择
静态
计划。与其他计划相比,
静态
的好处是,它不会引入必须协调任务分配的开销在运行时运行mong线程

要从运行代码的体系结构中获得最大的性能,还有很多东西需要研究。但是现在,我认为这是一个足够好的开始

for(i=1; i<= N-1; i++)
  {
    k = a + i*dx; //Suma del intervalo
    
    if(i%3 == 0)
    {
      resultado = resultado + 2 * f(k);
    }
    else
    {
      resultado = resultado + 3 * f(k);
    }
  }
 #pragma omp parallel reduction ( +: resultado) 
 for(i=1; i<= N-1; i++)
  {
    k = a + i*dx; //Suma del intervalo
    
    ... 
  }