C++ AMP 学习笔记

C++AMP 遇见C++ AMP 在GPU上做并行计算 阅读详情

 

C++ AMP是微软研究人员开发的一个并行计算库,有了它就可以让程序在为并行计算设计的硬件上运行(比如显卡)。和AMD鼓吹的OpenCL一样,C++ AMP也是一个开放的开发标准,所以与Nvidia的cuda不同,它并不依赖于特定的硬件(比如Nvidia的Geforce系列显卡)。目前微软提供了Visual Studio平台上的开发工具集(Intellisense, 调试,性能优化),未来可能会移植到其他平台上,比如UNIX或者Linux。

 

想用C++ AMP写程序,需要的配置有:

Windows 7或8操作系统;

Visual Studio 2012;

DirectX June 2010 SDK;

一块可以运行DirectX 11的显卡(大多数新显卡都可以)。

 

为什么要用显卡(GPU)做计算?

1. 显卡的浮点运算能力比CPU强。浮点运算能力一般用FLOPS(Floating Point Operations Per Second)来表示,1 GFLOPS = 1 GIGA FLOPS = 每秒十亿次浮点运算,1 TFLOPS = 1000 GFLOPS = 每秒一万亿次浮点运算。一颗最新的CPU(比如intel的i7系列)不过达到100GLOPS的运算能力,而AMD的7990系列显卡突破了8TFLOPS,几十倍于CPU。这是因为GPU拥有着更多的晶体管,因而也有着更多的计算资源,可以在计算速度方面完爆CPU。

 

2. GPU的功耗比CPU低。CPU的功耗大概可以低到1 Gflop/Watt,也就是每瓦电力可以提供1Gflops的计算能力。GPU的功耗可以达到10 Gflop/Watt。相当于消耗同样的电力,GPU可以做十倍的运算。

 

既然显卡计算能力这么强,为什么大多数人还是在CPU上编程呢?因为显卡并没有CPU那么完善的数据处理能力——例如多任务,读入/写出,随机存储等等。在面临复杂的算法时,还是CPU的处理显得游刃有余。所以GPU对现行计算的优化还只能集中在可以高度并行化的算法上,比如矩阵计算,图像处理等等。

 

说了这么多显卡,回来再说两句C++ AMP。微软本着“简约而不简单”的原则,一共只给C++增加了两个关键词:parallel_for_each和restrict。从名字可以看出来第一个是用来写并行代码的,restrict则是制定语言类型的(GPU执行还是CPU执行)。只要不在并行代码的部分,你尽可以使用C++的各种特性:模板,C++标准库等等。微软还贴心的送上了显卡加速的数学库,比如三角函数,幂函数,指数函数和平方倒数等等。

 

好吧,让我们看看到底怎么用C++ AMP写程序:

#include
using namespace concurrency; 
void AddArrays (int n, const int* const pA, const int * const pB, int * const pC) 
{ array_view  a (n, pA); 
 array_viewb (n, pB); 
 array_viewc (n, pC); 
 parallel_for_each (c.extent, [=] (index<1> idx) restrict(amp) { 
 c[idx] = a[idx] + b[idx]; 
 }); 
}

可见一段完整的C++ AMP代码需要至少以下几个部分:

1. amp.h头文件

2. 使用concurrency命名空间

3. 使用array_view将数据从内存拷贝至显卡

4. 使用parallel_for_each和lambda函数(之后会讲)完成运算

5. 使用restrict(amp)告诉编译器这一段是显卡加速代码

 

这段代码的目的是把两个一维数组a和b拷贝至显卡,然后把它俩的每个元素逐个相加后得到数组c,再把c拷贝回内存。我们先把这段代码放一会,看看C++ AMP中经常用到的几个概念。

 

*** array ***

并行计算的对象绝大多数是数组,array就是放在显卡上的一个数组。第一个参数T是数组类型,int代表整形,float代表单精度实数,double代表双精度实数。第二个参数N是数组的秩,N=1时为一维数组,T=2时为二维数组,最大可以定义128维数组(真的需要这么多维么)。

 

如果声明了一个array b(4,2),则代表这是一个二维实数数组,大小为4X2,也就是说一共4行2列,合计8个元素。

 

可以在声明array的时候顺便把内存里的数据也拷贝过来,像这样:

array a(5, v.begin(), v.end()); 

这里v是内存里的一个STL vector,被从头至尾拷贝至显卡中的a数组。

 

当然也可以先声明再拷贝:

array a (5);

copy(a,v);

 

*** extent ***

C++ AMP也允许把数组大小单独作为一个变量,叫做extent。像这样:

concurrency::extent<3> e(2,3,4); // e 将被用来规定一个三维数组的大小

array m(e, v.begin()); //生成一个显卡上的三维数组m,数组大小为2X3X4.

 

*** array_view ***

说完了array,之前那个例子中的array_view是干什么用的呢?如果说array相当于C++中一个独立变量的话,array_view则相当于一个指向变量的别名(reference)。array_view在创建时必须被初始化,也就是说它必须“有料”,这个“料”指的是内存上的某个数组,array_view就挂靠在这个内存名下。array则不同,前面已经提到过可以声明一个只有大小没有数据的array。如果改变了array_view的数据,它指向的那块内存区域的数据也会被改变。

 

干嘛放着好好的array不用去折腾这个array_view呢?这恰恰是微软研究人员的苦心所在:array_view给程序员免除了把数据从内存拷贝到显卡再从显卡拷贝至内存这个繁琐的过程。反正array_view是内存的好基友,在array_view中做的计算会被自动同步到内存中。

 

之前那段示例代码,如果用array写,会变成这样:

 

void AddArrays (int n, const int* const pA, const int * const pB, int * const pC) 
{ array  a (n);
  copy (pA, a); 
 array b (n); 
  copy (pB, b);
 arrayc (n); 
 parallel_for_each (c.extent, [=] (index<1> idx) restrict(amp) { 
 c[idx] = a[idx] + b[idx]; 
 }); 
 copy(c, pC);
}
可见使用array_view的好处。
 
*** parallel_for each ***
parallel_for_each是微软专门为C++ AMP添加的关键字,也是C++ AMP的核心。这里就是放并行代码的地方。再看下示例程序中的parallel_for_each 部分:
parallel_for_each (c.extent, [=] (index<1> idx) restrict(amp) { 
 c[idx] = a[idx] + b[idx]; 
 }); 
parallel_for_each的第一个参数c.extent告诉了显卡需要多少线程来进行计算。如果c是一个4x3x2的数组的话,则c.extent=(4,3,2),显卡会并发出24个线程。
parallel_for_each 的第二个参数[=] (index<1> idx)被称为lambda 函数。lambda函数是一个很有趣的迷你函数,它没有函数名,却有完整的函数体:
{ 
 c[idx] = a[idx] + b[idx]; 
 }); 
[=]叫做lambda函数的捕获从句(好小的从句),index<1> idx是lambda函数的参数。这样一个小小的函数几乎把C++里的括号类型用完了:[], (), {}。
为啥[]里是个=号呢?这是因为c数组的计算结果是通过值传递到内存的。如果用reference(别名)传递,就得用[&]了————好吧我也不知道自己在说啥。若想更深入学习C++的lambda函数,请猛戳:
http://msdn.microsoft.com/zh-cn/library/dd293608.aspx
C++ AMP对于这个lambda函数有什么要求呢?其实要求还挺多的。
1.lambda函数不可有返回值(这就要求它必须是void型)。
2.lambda函数一般只能有一个参数,就是线程号(例子中的idx)。
3.结尾必须是restrict (amp)。
4.它只能调用C++ AMP许可的数据类型。这些类型包括int, unsigned int, float, double, C型数组,array_view, array, 或者只包括以上类型的结构体。
下面这些类型是不能用的:
bool, char, short, long long, 以及这些类型的unsigned版本。
*** restrict (amp) ***
最后罗嗦几句这个restrict给C++ AMP带来的限制。其实lambda函数体内还可以调用其他的C++函数,但是既然是并行计算嘛,就得有些限制:
1.所有的函数都必须在编译代码时即确定的!这意味着被调用的C++函数必须是和lambda函数在同一个.cpp文件之中,或者在.cpp文件所包含的头文件之中。
2.如果非要在并行计算中使用类,请注意虚拟函数是不能用了。虚拟继承当然更没戏了。下面各种花哨的C++特性统统不能用:
今天就写到这吧,以后有时间继续八。
  • 递归
  • new / delete
  • goto
  • try/throw/catch
  • 全局变量,静态变量
  • 内嵌汇编

 

文章来源:

如哥的博客

http://blog.sina.com.cn/suantouge [订阅]

C++ AMP同CUDA之间的性能比较 通过500阶矩阵的乘法,大致比较下CPU、AMP、CUDA之间的性能差距。 阅读详情

相关推荐

C++ AMP 介绍(二)

C++ AMP 介绍(二) 最后更新日期:2014-05-02 阅读前提:《C++ AMP介绍(一)》 环境:Windows 8.1 64bit英文版,Visual Studio 2013 Update1英文版,Nvidia QuadroK600 显卡 内容简介          介绍C++ AMP的 array、array_view、extent类和平铺的知识。 正文 数据的移动

lee353086的专栏 6132

C++ AMP 概述

C++ AMP 概述 Visual Studio 2013 其他版本 C++ Accelerated Massive Parallelism (C++ AMP) 可加速 C++ 代码执行,方法是通过利用数据并行硬件(例如离散图像卡上的图像处理单元 (GPU))。 通过使用 C++ AMP,您可以为多维数据算法编码,以便通过使用异

lycnjupt的专栏 1114

C++ AMP

C++ AMP

C++AMP基础

C++AMP(AMP:Accelerated Massive Parallelism)是一个并行库和语言层面的小扩展,能够帮助在C++应用程序中实现异构计算。Visual Studio 2012及以上版本提供了新的工具和功能支持,可以用来调试和剖析C++AMP应用程序的性能,包括GPU调试和GPU并行可视化。对于适合数据并行计算的应用而言,可以实现显著的加速。微软官网的C++AMP结束,里面有入门...

m0_37357063的博客 1775

AMP元件库

这是标准amp的元件库。

Cloudflare 5秒盾逆向实战:13次请求背后的Python补环境框架搭建指南

本文深入解析了如何通过Python构建浏览器环境模拟框架,以应对Cloudflare 5秒盾等现代Web防护机制。文章详细拆解了其背后复杂的13次请求链,涵盖了JavaScript执行引擎集成、DOM事件模拟、网络请求控制及Canvas指纹等环境检测的完整实现方案,为自动化数据采集和逆向工程提供了实战指南。

gold的博客 356

C++AMP介绍(一)

C++AMP介绍(一) 最后更新日期:2014-05-02 阅读前提: 环境:Windows 8.1 64bit英文版,Visual Studio 2013 Professional Update1英文版,Nvidia QuadroK600 显卡 内容简介          介绍C++ AMP如何使用加速器(GPU)的并发执行能力。通过两个尽可能简洁的程序,让用户了解到如何把AMP应用到

lee353086的专栏 1万+

计组实验之四路表决器

请在之前四路表决器电路实现的基础上,继续用连接线 联接CD4511,将投票为1的票数总和显示到一个 LED上,思考如何做?由于我们需要通过显示字形来直接看出有几个1,在这里,我们最多有四个1,即显示字形最多到4就行,所以我们需要将有几个1用2进制数来表示,下面给出了相关电路图。显示输入插口,按真值表(自拟)要求,逐次改变输入变量, 测量相应的输出值,验证逻辑功能, 与表3-1 进行比较, 验证所设计的逻辑电路是否符合要求。用实验结果与真值表3-1和3-2进行比对,可以得出,我们实验结果是正确的。

szyugly的博客 1万+

linux下C/C++学习 &amp; socket

1、c的一个例子 (1)文本文件HelloWorld.c #include void main() {     printf("Hello World!\n"); } (2) 不生成HelloWorld.o,直接生成HelloWorld.exe gcc -o  HelloWorld.exe HelloWorld.c   生成HelloWorld.o

vestinfo的专栏 1895

Palabos User Guide中文解读 | 第一章 | 介绍

译者的话:本人在学习palabos时,发现国内中文资料甚少,恰好网上可以直接搜到palabos user guide这种英文资料,加之时间充裕,便打算开始翻译,能不能完成全本翻译再说,而且文中我也会标记我不确定的地方,以传达意思为主,翻译不当的地方还请各位读者帮忙指正。 Palabos User Guide Release 1.0 r1 Copyright © 2019 University of...

Yulan Fang's notes. 6978

柔性OLED屏幕绿线故障的激光修复技术解析

OLED显示技术作为新一代显示方案,其主动矩阵驱动原理通过TFT背板控制每个像素的发光。在柔性屏幕应用中,微米级数据线路的物理损伤会导致显示异常,表现为贯穿屏幕的绿线故障。激光微焊技术凭借其微米级加工精度,成为修复这类精密电路损伤的理想方案。该技术通过纳秒级脉冲激光实现金属线路的精准重熔,在手机维修、显示面板制造等领域具有重要应用价值。特别是在折叠屏、曲面屏等柔性显示设备维修中,激光修复技术能有效解决因反复弯折导致的数据线断裂问题,配合光学定位系统和参数优化,修复成功率可达85%以上。

weixin_29168153的博客 325

windows C++ 并行编程-C++ AMP(一)

C++ AMP (C++ Accelerated Massive Parallelism) 利用数据并行硬件(通常作为独立显卡上的图形处理单元 (GPU) 存在)来加速 C++ 代码的执行。 C++ AMP 编程模型包括多维数组、索引、内存传输和平铺的支持。 它还包括数学函数库。 可以使用 C++ AMP 语言扩展来控制如何在 CPU 与 GPU 之间来回移动数据。

王马的博客 1496

MATLAB从入门到精通-APP调用simulink中的参数,并且修改,将结果返回到APP中

本次案例为以下微分方程: 其中方程的初始值为: Step1:搭建simulink文件,如下图所示: 初始值配置在积分模块中,如下图所示: Step2:制作app 操作视频: ,时长01:11 代码: 本文包括APP如何回调simulik中d的参数,以及把simulink中的仿真结果输出到APP中的绘图界面中。 核心代码如下: ...

wenyusuran的专栏 3042

[C++]基于AMP的GPU并行计算

基于AMP的GPU并行计算 AMP简介 C++AMP (C++ Accelerated Massive Parallelism)利用并行硬件(例如独立图形加速卡)的性能,加速你C++程序的执行速度,C++ AMP编程模型包括支持多维数组,索引,内存传输和平铺,包括数学函数库。你可以使用C++ AMP更广泛的控制CPU同GPU之间数据的传递。 注意:C++ AMP要求你的显卡完整支持DirectX1...

Method.Jiao的博客 4826

本地部署AI应用:基于Google Gemini的banana-prompt快速上手指南

AI应用开发的核心在于将大模型能力集成到实际场景中,其原理是通过API调用将用户输入转化为模型可理解的指令,再由模型生成响应。这一技术价值在于降低AI应用开发门槛,实现数据本地化处理与隐私保护。在工程实践中,开发者常面临环境配置复杂、API集成繁琐等挑战。本文聚焦于使用banana-prompt工具包,通过TypeScript技术栈和npm包管理,快速在Windows本地部署基于Google Gemini API的AI应用。该方案特别适用于ai-prompts提示词工程和content-creation内容

weixin_27188815的博客 318

LM358模拟声音传感器原理图设计,已量产(声音传感器)

最近在做智能家居设备的声音触发模块时,搭了个基于 LM358 的模拟声音传感器电路 —— 不用复杂的专用芯片,靠通用运放就能把环境声音转化为可被单片机 AD 采集的电压信号,成本压得很低,实际调试下来灵敏度和稳定性都够用。今天把这个电路拆解开,聊聊每部分的设计思路。

不脱发的程序猿 474

基于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++ amp解决方案 5 结论 参考资料 http://ceur-ws.org/Vol-1746/paper-23.pdf 摘要: 如今,程序员面临的挑战是使他们的程序变得更好。“更好”一词意味着更简单,可移植且执行速度更快。 异构计算是计算机科学领域的一种新方法。 ..

love code, love life. 2424

基于MATLAB的变分模态分解(VMD)算法详解

变分模态分解(VMD)是一种先进的信号处理方法,通过变分框架将复杂信号分解为多个模态分量。相比传统经验模态分解(EMD),VMD具有坚实的数学基础,能有效抑制模态混叠和端点效应。其核心思想是将信号分解转化为约束优化问题,通过交替方向乘子法迭代求解各模态的中心频率和带宽。VMD在机械故障诊断、生物医学信号处理等领域展现出优越性能,尤其适合处理非平稳非线性信号。该算法通过严格的数学模型实现自适应频谱优化,为信号分析提供了更可靠的工具。

qq_42212808的博客 739

cpp是否完全替代c_CPP:AMP的标准替代方案

It’s no secret that I have reservations about Google’s AMP project in its current form. I do want to make it clear, though, that what bothers me has never been the technical side of things—AMP as a pe...

cunya6061的博客 584

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C++amp矩阵相乘

参考自:https://msdn.microsoft.com/en-us/library/hh873134.aspx #include <iostream> #include <amp.h> using namespace concurrency; // 常规矩阵相乘计算 void MultiplyWithOutAMP() { int aM...

along1155的博客 254

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

如何入门 C++ AMP 教程

本文告诉大家如何写一个 Helloworld 程序。 首先打开 VisualStudio ,大概现在也没有人还在用 VisualStudio 2013 了,所以我就不需要告诉大家需要用哪个版本的 VisualStudio ,如果我发现你的 VisualStudio 版本不对让程序运行错误,我就不会去回复。

lindexi 3427

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

8.1.C++ AMP简介

C++ AMP是专为设计支持C++的异构并行模型. 全程是: Accelerator Massive Parallelism 下面是一个Vector C++ AMP的代码,通过这段代码来解释C++ AMP的语法: #include &amp;lt;amp.h&amp;gt; using namespace concurrency; void vecAdd(float* A, float* B, fl...

weixin_34343308的博客 344
上一篇: C++ AMP 概述
下一篇: 第三篇:GPU 并行编程的运算架构
Poo_Chai
博客等级 码龄9年 178粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值