文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

多核中的并行前缀和计算分析

2024-04-02 19:55

关注

本篇内容介绍了“多核中的并行前缀和计算分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1、串行前缀和的计算

如果给定一个数列a[n],令S[k] = a[0]+a[1]+...+a[k],(k = 0, 1, 2…n-1),数列S[k]即为数列a[n]的前缀和。例如下面一列数据:

a[4] = {1,   2,   3,   4};

其前缀和为

S[0] = a[0] = 1;

S[1] = a[0] + a[1] = 1+ 2 = 3;

S[2] = a[0] + a[1] + a[2] = 1 + 2 + 3 = 6;

S[3] = a[0] + a[1] + a[2] + a[3] = 1 + 2 + 3 + 4 = 10;

前缀和的计算非常简单,一般地,可以用下面的函数来进行串行前缀和的计算:

  template <class T>  void Sequential_PrefixSum(T * pInput, T *pOutput, int nLen)  {      int i;         pOutput[0] = pInput[0];      for ( i = 1; i < nLen; i++ )      {          pOutput[i] = pInput[i] + pOutput[i-1];      }  }

在上面的串行前缀和计算代码中可以看出,每次循环都依赖于上一次循环的结果,因此无法直接对循环进行并行化,要进行并行化则必须修改计算方法,下面就来看如何进行并行前缀和的计算。

2、并行前缀和的计算

前缀和的并行计算方法有许多种,David Callahan的论文“Recognizing and Parallelizing Bounded Recurrences”中给出了一种适合共享存储多处理器系统中的有界递归计算的通用方法,前缀和计算属于有界递归计算的一个特例。下面先以一个实例来讲解整个并行计算的过程:

例:假设有4个处理器要计算16个整数的前缀和,这16个整数如下:

1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16

1步,先将上面数据平分成4组,每个处理器各计算一组数据的前缀和,如下所示:

1   2   3   4 5   6   7   8 9   10   11   12 13   14   15   16

1   3   6   10 5   11   18   26 9   19   30   42 13   27   42   58

2步,选取每组数据的***一个数据,对这几个数据计算前缀和,如下所示:

1  3  6   10 5   11   18   26 9   19   30   42 13   27   42  58

1  3  6   10 5   11   18   36 9   19   30   78 13   27   42  136

经过这步的计算后,可以很容易发现,每组的***一个数据的值已经变成了原始数据在它所处位置之前(包含本位置)的所有数据的和。例如:

36 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8

78 = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12

3步:从第2组数开始,将每组中的数(除***一个数外)加上它的前一组数的***一个数,即可得到所有数的前缀和。如下所示:

 (1 3 6 10) (5+10 11+10 18+10 36) (9+36 19+36 30+36 78)  (13+78 27+78 42+78 136

(1  3  6  10)  (15  21  28  36)  (45  55  66  78)  (91  105  120  136

从上面的计算过程可以看出,第1步和第3步都是很容易进行并行化计算,第2步中,由于计算量非常小,用串行计算即可,下面给出上面处理过程的代码实现:

#define  MIN_PRARLLEL_PREFIXSUM_COUNT    8192       template<class T>  void Parallel_PrefixSum(T * pInput, T *pOutput, int nLen)  {      int i;         int nCore = omp_get_num_procs();            if ( nCore < 4 || nLen < MIN_PRARLLEL_PREFIXSUM_COUNT )      {          Sequential_PrefixSum(pInput, pOutput, nLen);          return;      }            int nStep = nLen / nCore;      if ( nStep * nCore < nLen )      {          nStep += 1;      }     #pragma omp parallel for num_threads(nCore)      for ( i = 0; i < nCore; i++ )      {          int k;          int nStart = i * nStep;          int nEnd = (i+1) * nStep;          if ( nEnd > nLen )          {              nEnd = nLen;          }          pOutput[nStart] = pInput[nStart];          for ( k = nStart+1; k < nEnd; k++ )          {              pOutput[k] = pInput[k] + pOutput[k-1];          }      }         for ( i = 2; i < nCore; i++ )      {          pOutput[i * nStep - 1] += pOutput[(i-1) * nStep - 1];      }         pOutput[nLen-1] += pOutput[(nCore-1)*nStep - 1];     #pragma omp parallel for num_threads(nCore-1)      for ( i = 1; i < nCore; i++ )      {          int k;          int nStart = i * nStep;          int nEnd = (i+1) * nStep - 1;          if ( nEnd >= nLen )          {              nEnd = nLen - 1;          }          for ( k = nStart; k < nEnd; k++ )          {              pOutput[k] += pOutput[nStart-1];          }      }      return;  }

从上面并行前缀和的计算过程可以看出,它的计算量比串行前缀和的计算增加了差不多一倍,如果考虑程序中的实际开销,计算增加量还不止一倍。因此在双核CPU机器上,使用并行前缀和计算没有任何意义,只有在超过4核CPU机器上,它才有实用价值。

Parallel_PrefixSum()函数中,先是判断CPU核数是否小于4,并且判断了计算量是否不足,如果两个判断条件中有任何一个满足,则调用串行前缀核计算函数进行计算,然后才进行并行前缀和的计算。在并行计算时只是简单地将计算平摊到各个CPU上,没有考虑CPU核数较多情况下计算量平摊到各个CPU核上,线程粒度过小的问题,主要是为了不使代码看起来过于繁琐。如有需要可以修改成自动计算出最合适的线程数量(可能小于CPU核数),然后并行计算时使用相应的线程数量即可。

“多核中的并行前缀和计算分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯