windows C++ 并行编程-使用 Lambda 表达式

要在加速器上运行的 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";
    }
}

ambda 表达式必须包含一个索引参数和 restrict(amp)。 在此示例中,array_viewsum 对象排名为 1。 因此,lambda 语句的参数是排名为 1 的索引对象。 在运行时,lambda 表达式针对 array_view 对象中的每个元素执行一次。 

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 的索引对象。 在运行时,lambda 表达式针对 array_view 对象中的每个元素执行一次。

受 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) 中所述的限制。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值