04test

  • 固定步长num_step=10000000

不同模式求pi

1.PAD模式下

    #include <time.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "omp.h"
    #include <unistd.h>
    #define NUM_THREADS atoi(getenv("THREAD"))
    #define PAD 8 //跟CPU内存分配有关
    double step;
    static long num_steps;
    int main(int argc ,char *argv[])
    {
    // printf("%f\n",(int)getenv("THREAD"));
      double start_t, end_t;
      double total_t;
      start_t = omp_get_wtime();
      num_steps = 100000000;
      double  pi,sum[NUM_THREADS][PAD];
      pi=0.0;
      step = 1.0 / (double)num_steps; //将1平分成100000步
      omp_set_num_threads(NUM_THREADS); //设置要使用的线程数目
    #pragma omp parallel  //开始并发执行
      {
        double x;
        int id , i;
        id = omp_get_thread_num(); //获取每个线程的id编号
        //#pragma omp parallel for reduction(+:sum)
        for (i=id; i < num_steps; i = i + NUM_THREADS)
        {
          x = (i - 0.5) * step; 
          sum[id][0] += 4.0 / (1.0 + x * x);
        }
        //printf("%f\n",sum);
        //#pragma omp critical
        //pi+=sum*step;

      }
      int i;
      for (i = 0; i < NUM_THREADS; i++)
      {
        pi += sum[i][0] * step;
      }
      end_t = omp_get_wtime();
      total_t = end_t-start_t;
      printf("运行时间为%fs\t%.10f\n", total_t, pi);
      //printf("PATH%d\n",atoi(getenv("THREAD")));
      return 0;
    }

2.并行域

3.critical 制导

4.reduction制导

5.lastprivate制导

计算数列加和

两者之间效率差别的原因

  • PAD方法

    • 虽然使用了二维数组,防止了数据写入时的阻塞;但在求终止结果时使用了For循环

  • lastprivate制导

    • 对局部sum变量进行了深度拷贝,在退出for循环时,将结果存在各自的sum变量中,各个线程分别对全局变量K做累加

1.PAD方法

2.lastprivate制导

计算二维矩阵累加和累积

数组指针的理解

*符号表示获取指针指向的值,具体的来讲就是下面这张图的理解

数组指针

二维数据的累加

  • 在命令行使用export THREAD=10指定使用的线程数

  • 当数组变大是可能会超出栈空间,使用ulimit -s 10000临时提升栈空间

数组的累乘

矩阵的累乘
  • 在纸上比划一下就ok啦

Last updated