本节书摘来自异步社区出版社《C++ AMP:用Visual C++加速大规模并行计算》一书中的第3章,第3.6节,作者: 【美】Kate Gregory , Ade Miller,更多章节内容可以访问云栖社区“异步社区”公众号查看。

3.6 parallel_for_each

C++ AMP:用Visual C++加速大规模并行计算
parallel_for_each函数是C++ AMP的核心,也是并行操作发生的地方。我们可以构造数组然后给它赋值,也可以构造array_view,包装std::vector等CPU密集型数据结构中的数据。之后可以使用parallel_for_each遍历数组中的每个元素,或者使用array_view,或者访问部分数据。parallel_for_each操作extent对象,extent控制着执行线程的数量。

注意事项:
parallel_for_each的变体可以操作分组extent,稍微有点儿不同。第4章和第5章会讨论parallel_for_each的变体。
下面是第1章中出现过的程序示例:

#include <amp.h>
using namespace concurrency;void AddArrays(int n, const int* const pA, const int* const pB, int* const pC)
{array_view<int,1> a(n, pA);array_view<int,1> b(n, pB);array_view<int,1> c(n, pC);parallel_for_each(c.extent, [=](index<1> idx) restrict(amp){c[idx] = a[idx] + b[idx];});
}```
上述代码对每一个原始指针(假定是C风格的数组)都使用了`array_view`,这些原始指针指向待增加的一维矩阵。每一个`array_view`都是一维的,范围为n,里面存的是整数。`parallel_for_each`的第一个参数是范围`c,array_view`存的是结果。在这个增加一维矩阵的案例中,大小(extent各维的乘积)和这三个数组视图是相同的,但在许多其他算法中,需要考虑如何挑选合适的范围值来执行线程。第二个参数是实际执行计算的`lambda`函数。在这个例子里,`lambda`是按值传入参数的。只有数组可以按引用传值(而且也只能按引用传值),其他所有类型,包括`array_view`实例,都是按值传参的。当数组传入`parallel_for_each`时,会返回与该数组相关的`accelerator_view`(可能是默认加速器上的默认视图)。如果什么也确定不了(例如,只有`array_view`的实例传入lambda表达式),那么不管运行系统上有什么加速器,`parallel_for_each`都会在默认加速器上运行。(如果要指定运行加速器,可以选择使用以`accelerator_view`作为参数的`parallel_for_each`重载函数。)lambda表达式可以使用新引入的restrict关键字修饰,`restrict`指示编译器要保证没有什么内容不适合在加速器上运行。实际限制我们后面马上会讲到。如果你碰巧写过一个函子(`functor`),或者计算要重复在代码多处执行,就可以用函子来代替`lambda`。但是,在这些例子里,lambda是一种自然选择,代码的可读性会因为`lambda`的存在而变得更好。第12章里给出了一个使用`parallel_`
`for_each的函子的例子。加速器针对范围内的每个元素都会启动一个线程。在上述代码示例中,c是一维`array_view`,范围取值是n,因此加速器上会启动n个线程,每个线程都会计算c的一个元素。如果c的范围是`(2,3,4`),那么加速器上运行的就是`24(2×3×4)`个线程。当然,把这么小的网格转移至加速器,根本不会意识到有什么性能提升,因为来回复制数据的成本时间已然超过了节省下来的时间。如果问题空间的计算量上升到百万级,例如范围取值为`(200,200,200`)的三维网格,而且计算也不只是把内部元素加进来这么简单,那么我们很可能就能看到巨大的性能提升。`parallel_for_each`要把正确答案计算出来,线程之间就必须得是相互独立的。执行顺序是没有保证的,例如,不可能让某个线程一直等待,直到某个其他线程计算出数值,或者线程之间进行通信。各线程要执行的lambda或函子(`functor`)等“内核函数”有以下三个特征。返回值类型是void。不管做的是何种计算,都应该在一个或多个数组元素或数组视图中保存。
在不分组(默认)的情况下,只有一个索引(范围的维度)。该索引的作用是确定计算的输入值,以及在哪里保存计算结果。
要使用`restrict(amp)`或`restrict(amp, cpu)`标记。
仅调用在代码生成时显式使用`restrict(amp)`或`restrict(amp, cpu)`标记的函数。这种函数的实现会在同样的`.cpp`文件里,或者是在该.cpp文件所包含的头文件的内联函数中,或者如果打开了链接时代码生成开关(`link time code generation,/ltcg`),也可能会位于链入的一个.cpp文件中。从独立执行文件中导入的函数,或者从`.lib`以及`.obj`导入的函数(没有使用`/ltcg`开关),在代码生成时是不可见的。当然,同样的限制规则也适用于从内核函数中被调用的函数。编译器必须将整个调用图内联进来才行。
参数不能是按引用传值的(除了数组实例以外)。按值传入是可以的。
传入加速器的参数类型要兼容,下节会讨论这一点。
注意事项:
在一些实际应用里,有些代码可能既想用来作`parallel_for_each`的内核,又想用于其他意图。面对这种场景,你可能需要略微放松`C++ AMP`官方文档中列举出来的那些条件规则。例如,允许函数有返回值,但`parallel_for_each`会忽视它。函数的参数除了可以是索引以外,还可以是有默认值的可选参数。如果你现在写的核函数只是要配合`parallel_for_each`使用,一般刚开始用C++ AMP的时候干的也就这点事儿,不掌握这些技术手法也没有什么问题。

《C++ AMP:用Visual C++加速大规模并行计算》——3.6 parallel_for_each相关推荐

  1. 蚂蚁链开源跨链技术 加速大规模创新应用“涌现”

    作者 | 董世晓 出品 | CSDN(ID:CSDNnews) 众所周知,在信息互联网时代的相当长的时间里,企业内部各系统间服务与数据不共享,造成了烟囱林立.孤岛横生,难以适应复杂变化快速的业务.为解 ...

  2. MPP大规模并行计算数据库与分布式数据库的区别

    最近调研分布式TP数据库.结合公司使用的MPP数据库,一度感觉两者很像,随着分布式的深入研究,结合行内MPP数据库使用过正中遇到的问题,简单的总结一下分布式数据库与MPP数据库的区别. 分布式数据库系 ...

  3. matlab sort三维_三维数组存储顺序

    理解C语言--从小菜到大神的晋级之路(9)--多维数组 本节视频链接:点击这里 1.多维数组的定义和结构 一个数组中可以支持各种数据类型,那么一个数组中的每一个元素同样也可以是一个数组.对于上次提到的 ...

  4. Auto CAD硬件加速——运行效果瞬间起飞

    前一段时间经常会有同学问这样一些问题: 什么是硬件加速?开不开对AutoCAD有什么影响? (通常这个时候回应我的是一对迷茫的眼神:我是谁,我在哪里,我在干什么--不对,是这是啥?这啥用?这咋用?) ...

  5. C++ AMP实战:绘制曼德勃罗特集图像

    本文转自:http://www.cnblogs.com/Ninputer/archive/2012/01/03/2310945.html 之前我写了一篇用GPU绘制曼德勃罗特(Mandelbrot)集 ...

  6. C++ AMP 实战:绘制曼德勃罗特集图像

    转自:http://www.oschina.net/question/54100_37584 之前我写了一篇用GPU绘制曼德勃罗特(Mandelbrot)集图像的文章,里面使用的技术是与DirectX ...

  7. 基于c++ amp的gpu编程

    目录 摘要: 1 简介 2 性能改进 2.1 异构平台 2.2 gpu架构 2.3 通过平行的性能改进 3 gpu编程架构 3.1 opencl 3.2 cdua 3.3 c++ amp 4 一个c+ ...

  8. 【C++学习】GPU编程的简单学习

    GPU是什么 显卡的处理器称为图形处理器(GPU),它是显卡的"心脏",与CPU类似,只不过GPU是专为执行复杂的数学和几何计算而设计的,这些计算是图形渲染所必需的.某些最快速的G ...

  9. 从最强AI算力到“元脑”2.0,智算加速产业变革

    作者 | Just 出品 | AI科技大本营(ID:rgznai100) AI模型的数据量.结构的复杂程度不断增加,带来了大规模AI算力的庞大需求. 2020年7月,OpenAI实验室推出拥有1750 ...

  10. 深入了解AI加速芯片的定制数据流架构与编译器 | 公开课

    随着人工智能时代的来临,业内对于更高效率算力的需求也越来越紧迫,而传统的 CPU 计算能力弱,只适合软件编程,并不适合应用于人工神经网络算法的自主迭代运算. 为了满足支撑深度学习的大规模并行计算的需求 ...

最新文章

  1. 模拟器抓取https方法
  2. 大数据流通与交易技术国家工程实验室成立大会在京举行
  3. 账单比较java代码_Java代码比较两个文件的MD5
  4. 在游戏运营行业,Serverless 如何解决数据采集分析痛点?
  5. C# 系统应用之调用SDelete程序粉碎文件及基础原理知识
  6. 批量管理Linux服务器,命令行工具Omnitty
  7. 在Java EE 7和WildFly中使用Bean验证来验证JAX-RS资源数据
  8. unity 彩带粒子_iOS动画开发----粒子系统---彩带效果
  9. java swing 代码_java swing编写gui生命游戏代码,新手上路
  10. 一些用xib加载主界面的过程
  11. ercharts一个页面能放几个_echarts 一个页面多个节点共用一个图表实例
  12. “丧文化”的祖师:波德莱尔:不懂得使自己的孤独为众人接受的人,也不懂得在碌碌众生中自立。...
  13. UI设计——以网易云音乐为例
  14. Mybatis-----实验小结
  15. WebStorm下载与安装2022版教程注册码WebStorm使用配置
  16. 基于模拟退火算法的TSP算法
  17. 日本人的姓及一些姓氏的读法(转)
  18. Ubuntu 12.04 Eclipse 3.7 紧凑布局样式美化
  19. 云信api_云信Web SDK API文档
  20. 命令行的艺术( the-art-of-command-line )

热门文章

  1. jlink v9可升级固件‘_在rt-thread下实现OTA在线固件更新功能
  2. PHP调用微信发放现金红包接口
  3. WireShark下载:官网、源码
  4. 终于完成了:为什么吾非要亲自搞CDKEY
  5. maven打包时加入依赖jar包
  6. debian编译openjdk8
  7. 成功的人不是最聪明的那个人,但绝对是一个交流很棒的人
  8. SHELL下根据进程号得到内存,并截取为整数
  9. word提示“无法创建工作文件,请检查临时环境变量”的解决办法
  10. 计算机桌面上的声音图标没了怎么办,电脑桌面的音量图标不见了怎么办