《C++ AMP:用Visual C++加速大规模并行计算》——3.7 使用restrict(amp)标记的函数

3.7 使用restrict(amp)标记的函数

C++ AMP:用Visual C++加速大规模并行计算
要想成功地使用restrict(amp)编译,函数必须遵守许多规则。头一条规则我们在3.6节中提到过,与其调用的函数有关。这些规则必须在代码生成时是可见的,也必须使用restrict(amp)进行标记。如果我们没有使用链接时代码生成,基本上就意味着它们一定要和编译时的.cpp文件相同,也可以使用那个.cpp文件中包含的头文件带进来。如果在编译两个.cpp文件(一个调用函数的和一个实现函数的)时,还有链接时,使用/ltcg开关,那么调用函数和被调用函数就可以放在各自独立的文件里。

C++ AMP兼容函数或lambda表达式只能使用C++ AMP兼容类型,它们包括:

int
unsigned int
float
double
C风格的intunsigned int、floatdouble数组
concurrency::array引用或concurrency::array_view
只含有C++ AMP兼容类型的结构体
这也意味着某些数据类型是禁止使用的:

bool(可以在lambda表达式中用于本地变量)
char
short
long long
上述类型的无符号版本
引用和指针(指向兼容类型)可以在本地使用,但不能传入lambda。函数指针、指向指针的指针等不能使用;静态变量或全局变量也不能使用。

如果要使用类实例,那么类必须满足更多规则。它们不能是虚函数或虚拟继承。构造函数、析构函数以及其他非虚函数都可以使用。成员变量必须全部是兼容类型,当然也可以包含其他类的实例,只要这些类能满足相同的规则。

amp兼容函数中的实际代码不是在CPU中运行的,因此不能用来做下面的事情:

递归
指针类型转换
使用虚函数
newdelete
RTTI或动态类型转换
goto
throwtrycatch
访问全局变量或静态变量
内联汇编
如果我们违反了这些规则,那么看看编译器抛出的错误消息会有所帮助。下面的代码满足所有规则,可以无错编译:

std::vector<int> v(5);
std::iota(v.begin(), v.end(), 0);
array<int, 1> a(5, v.begin(), v.end());
parallel_for_each(a.extent, [&](index<1> idx) restrict(amp)
{
   a[idx] = a[idx] * 2;
});```
现在把lambda中没有使用restrict(amp)标记的调用函数替换掉,但还放在同一个.cpp文件里,我们会看到下面的提示(DoubleIt是被调用函数的名字):

error C3930: 'DoubleIt' : no overloaded function has restriction specifiers that are compatible
with the ambient context```
如果函数有对应的限制,但在代码生成时不可见,那么我们也会看到这条消息。

如果我们使用short等类型,会因为restrict(amp)代码并不支持它们,而会看到如下的错误消息:

error C3581: 'short': unsupported type in amp restricted code
如果尝试声明指向指针的指针或者其他未经支持的类型,都会看到同样的消息。

时间: 2024-10-31 05:39:46

《C++ AMP:用Visual C++加速大规模并行计算》——3.7 使用restrict(amp)标记的函数的相关文章

《C++ AMP:用Visual C++加速大规模并行计算》——1.2 CPU并行技术

1.2 CPU并行技术 C++ AMP:用Visual C++加速大规模并行计算 减少应用程序串行部分耗时的一种方法是尽量降低其串行性,重新设计应用程序,充分利用CPU并行和GPU并行.虽然GPU可以同时拥有成千上万个线程,而CPU要少得多,但利用CPU的并行性也能对整体加速比有所帮助.理想情况下,CPU并行技术和GPU并行技术是兼容的,方法也有很多. 1.2.1 向量化 SIMD是一种能使处理速度变得更快的重要方法,也即单指令流多数据流(Single Instruction, Multiple

《C++ AMP:用Visual C++加速大规模并行计算》——1.3 C++ AMP方法

1.3 C++ AMP方法 C++ AMP:用Visual C++加速大规模并行计算 C++ AMP是一个并行库和语言层面的小扩展,能够帮助在C++应用程序中实现异构计算.(AMP是Accelerated Massive Parallelism的缩写,即加速大规模并行.)Visual Studio提供了新的工具和功能支持,可以用来调试和剖析C++ AMP应用程序的性能,包括GPU调试和GPU并行可视化.有了C++ AMP以后,主流C++开发人员可以使用熟悉的工具来创建可移植的.不会过时的应用程序

《C++ AMP:用Visual C++加速大规模并行计算》——1.1 为什么选择GPGPU?什么是异构计算?

1.1 为什么选择GPGPU?什么是异构计算? C++ AMP:用Visual C++加速大规模并行计算 作为开发者,面对周围不断变化的世界,努力调整自己,这种生活我们早已习以为常.IT行业对世界的影响自成体系.我们学习新的语言,使用新的方法,考虑采用新的用户界面,并理所当然地认为它们都能让我们的程序变得更好.为了让下一版比上一版更完善,如果认为采用某种方法会碰壁,我们就会转而换用另外一种方法.而有些开发者现在要使用的最新方法就是异构计算. 本章将回顾计算性能提升的历史,让读者们看看开发者们都碰

《C++ AMP:用Visual C++加速大规模并行计算》——3.9 数学库函数

3.9 数学库函数 C++ AMP:用Visual C++加速大规模并行计算 如前所述,我们不能只在parallel_for_each中调用来自"核函数"的函数.调用函数应该在代码生成时可见,应该使用restrict(amp)标记.如果我们要转换现有代码,就需要做出必要的调整.我们也有可能会调用sqrt()或sin()等库函数.因此,需要使用加速器兼容版本替换这些调用.好消息是amp_math.h里定义了成百上千的此类函数,它们全都在命名空间concurrency::fast-math

《C++ AMP:用Visual C++加速大规模并行计算》——3.8 在CPU和GPU之间复制数据

3.8 在CPU和GPU之间复制数据 C++ AMP:用Visual C++加速大规模并行计算 数据可以在CPU和加速器(通常是GPU)之间自动复制,也可以根据需要使用amp.h中众多的copy()重载函数之一显式复制.例如,我们可以在默认加速器上构造array,然后仅使用一条函数调用便可以把数据复制进去: array<int, 1> a(5, v.begin(), v.end()); 此外,我们还可以构造空数组,然后再使用copy()函数来加载数据.array_view在CPU上有一个对应容

《C++ AMP:用Visual C++加速大规模并行计算》——3.1 array &lt; T,N &gt;

3.1 array < T,N > C++ AMP:用Visual C++加速大规模并行计算 对于C++ AMP开发者来说,头等重要的就是array.array模板位于concurrency命名空间,有两个参数:一个是集合元素的类型,另一个是秩(rank)或者说维数.我们日常工作中使用的多是一维.二维或三维数组,但C++ AMP并没有限制我们只用到三维,如果我们需要,最多可以用到128维! 正常情况下,array是加速器(一般是GPU)上的一组信息(相同类型的).array其实是在accele

《C++ AMP:用Visual C++加速大规模并行计算》——第1章 C++ AMP概述

第1章 C++ AMP概述 C++ AMP:用Visual C++加速大规模并行计算 通过本章的学习,读者将会了解: 为什么选择GPGPU?什么是异构计算? CPU并行技术 C++ AMP方法 小结

《C++ AMP:用Visual C++加速大规模并行计算》——1.4 小结

1.4 小结 C++ AMP:用Visual C++加速大规模并行计算 本章描述了异构计算适合处理的问题类型,以及过去数十年间应用程序性能提升的历史.还介绍了C++ AMP,解释了设计C++ AMP的动机.本书其余各部分将会更详细地解释C++ AMP的类库和语言扩展,演示如何使用更先进的技术,使应用程序获得最大的性能提升,展示如何使用Visual Studio的支持功能.有些主流开发人员对通过C++ AMP利用异构感兴趣,本书也为他们提供了指导.

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

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控制着执行