共用方式為


使用 lambda、函式物件與受限函式

你想在加速器上執行的 C++ AMP 程式碼,會在呼叫 parallel_for_each 該方法時指定為參數。 你可以提供 lambda 運算式或函式物件(函子)作為該參數。 此外,lambda 運算式或函式物件也可以呼叫 C++ AMP 限制函式。 本主題使用陣列加法演算法來展示 lambda、函數物件與受限函數。 以下範例展示了未使用 C++ AMP 程式碼的演算法。 會建立兩個長度相等的一維陣列。 對應的整數元素會被加入並儲存在第三個一維陣列中。 不使用 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 表達式語法

功能物件

你可以把加速器程式碼分解到函式物件裡。

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-Restricted 函式

你可以進一步分解加速器程式碼,方法是建立一個受限的函式,然後從 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)