要在加速器上运行的 C++ AMP 代码在调用 parallel_for_each 方法时指定为参数。 可以将 lambda 表达式或函数对象(functor)作为该参数提供。 此外,lambda 表达式或函数对象还可以调用 C++ AMP 受限函数。 本主题使用数组加法算法来演示 lambda、函数对象和受限函数。 以下示例演示没有 C++ AMP 代码的算法。 将创建两个长度相等的 1 维数组。 相应的整数元素将添加并存储在第三个 1 维数组中。 不使用 C++ AMP。
void CpuMethod() {
int aCPP[] = {1, 2, 3, 4, 5};
int bCPP[] = {6, 7, 8, 9, 10};
int sumCPP[5];
for (int idx = 0; idx <5; idx++)
{
sumCPP[idx] = aCPP[idx] + bCPP[idx];
}
for (int idx = 0; idx <5; idx++)
{
std::cout <<sumCPP[idx] <<"\n";
}
}
Lambda 表达式
使用 lambda 表达式是使用 C++ AMP 重写代码的最直接方法。
void AddArraysWithLambda() {
int aCPP[] = {1, 2, 3, 4, 5};
int bCPP[] = {6, 7, 8, 9, 10};
int sumCPP[5];
array_view<const int, 1> a(5, aCPP);
array_view<const int, 1> b(5, bCPP);
array_view<int, 1> sum(5, sumCPP);
sum.discard_data();
parallel_for_each(
sum.extent,
[=](index<1> idx) restrict(amp)
{
sum[idx] = a[idx] + b[idx];
});
for (int i = 0; i <5; i++) {
std::cout <<sum[i] <<"\n";
}
}
lambda 表达式必须包含一个索引参数,并且必须包含 restrict(amp)。 在此示例中, array_viewsum 对象排名为 1。 因此,lambda 语句的参数是排名为 1 的 索引 对象。 在运行时,lambda 表达式针对 array_view 对象中的每个元素执行一次。 有关详细信息,请参阅 Lambda 表达式语法。
Function 对象
可以将加速器代码分解为函数对象。
class AdditionFunctionObject
{
public:
AdditionFunctionObject(const array_view<int, 1>& a,
const array_view<int, 1>& b,
const array_view<int, 1>& sum)
: a(a), b(b), sum(sum)
{
}
void operator()(index<1> idx) restrict(amp)
{
sum[idx] = a[idx] + b[idx];
}
private:
array_view<int, 1> a;
array_view<int, 1> b;
array_view<int, 1> sum;
};
void AddArraysWithFunctionObject() {
int aCPP[] = {1, 2, 3, 4, 5};
int bCPP[] = {6, 7, 8, 9, 10};
int sumCPP[5];
array_view<const int, 1> a(5, aCPP);
array_view<const int, 1> b(5, bCPP);
array_view<int, 1> sum(5, sumCPP);
sum.discard_data();
parallel_for_each(
sum.extent,
AdditionFunctionObject(a, b, sum));
for (int i = 0; i <5; i++) {
std::cout <<sum[i] <<"\n";
}
}
函数对象必须包含构造函数,并且必须包含函数调用运算符的重载。 函数调用运算符必须包含一个索引参数。 函数对象的实例作为第二个参数传递给 parallel_for_each 方法。 在此示例中,将三 个array_view 对象传递给函数对象构造函数。
array_view对象sum排名为 1。 因此,函数调用运算符的参数是排名为 1 的 索引 对象。 在运行时,该函数针对 array_view 对象中的每个元素执行一次。 有关详细信息,请参阅 C++ 标准库中的函数调用和函数对象。
C++ AMP-受限函数
可以通过创建限制性函数并从 lambda 表达式或函数对象调用它来进一步分解加速器代码。 下面的代码示例演示如何从 lambda 表达式调用受限函数。
void AddElementsWithRestrictedFunction(index<1> idx, array_view<int, 1> sum, array_view<int, 1> a, array_view<int, 1> b) restrict(amp)
{
sum[idx] = a[idx] + b[idx];
}
void AddArraysWithFunction() {
int aCPP[] = {1, 2, 3, 4, 5};
int bCPP[] = {6, 7, 8, 9, 10};
int sumCPP[5];
array_view<int, 1> a(5, aCPP);
array_view<int, 1> b(5, bCPP);
array_view<int, 1> sum(5, sumCPP);
sum.discard_data();
parallel_for_each(
sum.extent,
[=](index<1> idx) restrict(amp)
{
AddElementsWithRestrictedFunction(idx, sum, a, b);
});
for (int i = 0; i <5; i++) {
std::cout <<sum[i] <<"\n";
}
}
受限函数必须包含 restrict(amp) 并符合 限制 (C++ AMP) 中所述的限制。
另请参阅
C++ AMP(C++加速大规模并行度)
Lambda 表达式语法
函数调用
C++ 标准库中的函数对象
限制(C++ AMP)