什么是 GPU
主板的处理器称为图形处理单元(GPU),它是主板的“心脏”,类似于CPU,只不过GPU的设计目的是执行图形渲染所需的复杂物理和几何计算。 一些最快的 GPU 集成的晶体管甚至比普通 CPU 还要多。
GPU 已经成熟到可以轻松执行现实生活中的应用程序,但程序的运行速度比使用多核系统时要快得多。 未来的估计框架将是并行核GPU和多核CPU一起运行的混合系统。
GPU编程语言的选择,这里有一篇文章讲得很详细。
我总结了
我收到的学习也是基于C++AMP的。
C++ AMP
AMP的全称是AcceleratedMassiveParallelism(加速大规模并行估计),是Google提出的一个基于C++的异构并行估计平台。
我们通过一个小反例来简单的学习一下AMP的使用。
#include
// 需要引用
#include
// AMP模版的命名空间
using namespace concurrency;
const int size = 5;
void CppAmpMethod() {
int aCPP[] = {1, 2, 3, 4, 5};
int bCPP[] = {6, 7, 8, 9, 10};
int sumCPP[size];
// Create C++ AMP objects.
array_view<const int, 1> a(size, aCPP);
array_view<const int, 1> b(size, bCPP);
array_view<int, 1> sum(size, sumCPP);
sum.discard_data();
parallel_for_each(
// Define the compute domain, which is the set of threads that are created.
sum.extent,
// Define the code to run on each thread on the accelerator.
[=](index<1> idx) restrict(amp)
{
sum[idx] = a[idx] + b[idx];
}
);
// Print the results. The expected output is "7, 9, 11, 13, 15".
for (int i = 0; i < size; i++) {
std::cout << sum[i] << "n";
}
}
数组视图类
template <
typename _Value_type, // array_view 对象中的元素的数据类型。
int _Rank // array_view 对象的秩。所谓的秩指的是维度,如果省略则为1。
>
远程使用场景分为三种:
1.系统内存指针的视图通过并行_for_each调用传递到加速器并在加速器上访问。
2. 使用parallel_for_each 将加速器驻留数组的视图传递到另一个加速器视图并在那里进行访问。
3. 在CPU 上访问加速器驻留阵列的视图。
综上所述,加速器与加速器、加速器与cpu、加速器与系统内存都要经过array_view类。
array_view类相当于一个socket,一个连接。
和。 丢弃_数据();
丢弃数据
通常,您的算法可能需要纯粹使用 array_view 作为输出,并且当前内容 soft hearray_view 是重要的。 当访问任何加速器视图上的此类输出 array_view 进行计算时,将 array_view 底层的当前内容复制到加速器是不合需要的。 card_data 方法用于向其他运行时指示 array_view 下的数据部分的内容并不有趣,并且在 Accelerator_view 上访问 array_view 时不需要复制,其中 array_view 尚未准备好缓存。在 array_view 中调用此方法可以快速删除 array_view 引用的数据部分的现有内容,并适用于 array_view 和所有其他 array_view这是它的部分或预测。
实际上你的算法需要使用 array_view 作为输出,并且当前 array_view 的内容并不重要,访问 array_view 进行输出对于任何加速器来说都是不好的。 C++AMP提供了discard_data(丢弃数据)方法来表示运行时,一部分数据对array_view来说不重要,当array_view被加速器访问时,不需要将其复制到加速器中。 时间,不要缓存它。 这种调用array_view的方法可以看做是丢弃了array_view中的部分数据内容,适用于array_view和所有array_view,等等等等(最后一句看不懂)。
我自己翻译的,不知道对不对,如有问题请强调。
总而言之,一句话,如果array_view的对象不需要复制到加速器中,就使用discard_data。
比如sum作为输出容器显卡参与源码编译,上面的内容一开始并不重要,不需要复制到加速器中。
数组视图
添加const表示这个对象是只读的,我们不会改变它上面的内容。 其实这部分内容也是很难舍弃的。
Parallel_for_each函数(C++AMP)具体参数(msdn)
当 parallel_for_each 运行时,将为评估域中的每个索引运行并行活动。
通常在 GPU 计算机上运行。
parallel_for_each的句型之一
_模板<
int_Rank,
类型名称_内核_类型
我们看第一个参数sum.extent
表示一个由 N 个整数值组成的向量,指定最初为 0 的 N 维空间的边界。向量中的值按从最高有效到最低有效的顺序排列。
看一个反例,msdn的
int aCPP[] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
// There are 3 rows and 4 columns, and the depth is two.
array_view<int, 3> a(2, 3, 4, aCPP);
std::cout << "The number of columns is " << a.extent[2] << "n";
std::cout << "The number of rows is " << a.extent[1] << "n";
std::cout << "The depth is " << a.extent[0]<< "n";
std::cout << "Length in most significant dimension is " << a.extent[0] << "n";
构造一个3行4列、深度为2的字段显卡参与源码编译,通过extent[n]得到各个维度的厚度。
即指定GPU的线程数。
紧邻 lambda 的是 limit(amp),这是对 amp 的约束。
它的使用有很多限制
严格 (amp) 子句的功能具有以下限制:
带有restrict(amp)子句的函数必须遵守以下限制
该函数只能调用具有 strict(amp) 子句的函数。
函数只能由也具有restrict(amp) 子句的其他函数调用
该函数必须是可内联的。
函数必须是内联的
该函数只能声明 int、unsigned int、float 和 double 变量以及类和
仅包含这些类型的结构。 boolis 也是允许的,但如果在复合类型中使用它,它必须是 4 字节对齐的。
此函数只能由 int、unsignedint、float 和 double 变量以及类和类使用
结构体(包括其他类型)声明,bool也可以。 如果它是一致类型,则它必须是四字节对齐的。
Lambda 函数无法通过引用捕获,也无法捕获指针。
Lambda 函数无法捕获任何引用和 this 指针
仅支持引用和单间接指针作为局部变量、函数参数和返回类型。
仅局部变量、函数参数和返回类型支持引用和间接指针
以下行为是不允许的:
以下行为是不允许的
递归。
递归(天==为什么不让递归使用)
使用 volatile 关键字声明的变量。