千家信息网

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

发表于:2025-11-13 作者:千家信息网编辑
千家信息网最后更新 2025年11月13日,本篇内容介绍了"多核中的并行前缀和计算分析"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、串行前缀
千家信息网最后更新 2025年11月13日多核中的并行前缀和计算分析

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

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;

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

/**   串行前缀和计算函数            @param  T * pInput - 输入数据          @param  T *pOutput - 输出数据(前缀和)            @param  int nLen - 输入数据长度              @return  void - 无  */  template   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     /**   并行前缀和计算函数            @param  T * pInput - 输入数据          @param  T *pOutput - 输出数据(前缀和)            @param  int nLen - 输入数据长度              @return  void - 无  */  template  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核数),然后并行计算时使用相应的线程数量即可。

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

前缀 数据 函数 过程 处理 输入 代码 处理器 数列 方法 核数 线程 面的 循环 输出 多核 分析 实用 个数 内容 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发的结算方式 国产云计算数据库技术 服务器登录账号密码 威斯特电梯服务器 数据库如何取当前位子的上条数据 计算机网络技术的挑战 数据库审计服务报价 创建数据库的命令 软件开发标书质量保障措施 逍遥魔兽服务器外网架设教程 关于加强网络安全和隐私保护 女生做软件开发难找工作吗 查看服务器记录 cod17失去与暴雪游戏服务器 网络安全感目标是什么 梅州市网络安全宣传周启动 世界神奇服务器 网络安全攻防大赛培训 数据库为什么要分组管理 个人电脑装数据库会影响性能吗 e9000服务器性能 手机服务器无反应是什么原因 兆物网络技术有限公司是国企 应用软件开发流程是 计算机网络技术志向 电脑桌面应用软件开发 数据库检索电话是135开头的 在线计算机列表服务器可以禁止吗 潍坊软件开发公司规模排行 湖南乐悦互联网科技有限公司
0