Sdílet prostřednictvím


Používání parametrů Lambda, objektů funkcí a omezených funkcí

Kód C++ AMP, který chcete spustit na akcelerátoru, je určen jako argument ve volání parallel_for_each metody. Jako argument můžete zadat výraz lambda nebo objekt funkce (functor). Kromě toho výraz lambda nebo objekt funkce může volat funkci s omezeným přístupem C++. Toto téma používá algoritmus sčítání polí k předvedení lambda, objektů funkcí a omezených funkcí. Následující příklad ukazuje algoritmus bez kódu C++ AMP. Vytvoří se dvě 1rozměrná pole se stejnou délkou. Odpovídající celočíselné prvky se přidají a uloží do třetího dimenzionálního pole. C++ AMP se nepoužívá.

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";
    }
}

Výraz lambda

Použití výrazu lambda je nejpřímější způsob použití C++ AMP k přepsání kódu.

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";
    }
}

Výraz lambda musí obsahovat jeden parametr indexování a musí obsahovat restrict(amp). V příkladu má objekt array_viewsum pořadí 1. Parametr příkazu lambda je proto objekt indexu, který má pořadí 1. Za běhu se výraz lambda spustí jednou pro každý prvek v objektu array_view . Další informace naleznete v tématu Syntaxe výrazu lambda.

Objekt Function

Kód akcelerátoru můžete faktorovat do objektu funkce.

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";
    }
}

Objekt funkce musí obsahovat konstruktor a musí obsahovat přetížení operátoru volání funkce. Operátor volání funkce musí obsahovat jeden parametr indexování. Instance objektu funkce je předána jako druhý argument parallel_for_each metoda. V tomto příkladu se do konstruktoru objektu funkce předají tři array_view objekty. Objekt array_view sum má pořadí 1. Parametr operátoru volání funkce je proto objekt indexu, který má pořadí 1. Za běhu se funkce spustí jednou pro každý prvek v array_view objektu. Další informace naleznete v tématu Volání funkce a objekty funkce ve standardní knihovně jazyka C++.

Funkce C++ AMP-Restricted

Kód akcelerátoru můžete dále faktorovat vytvořením omezené funkce a jejím voláním z výrazu lambda nebo objektu funkce. Následující příklad kódu ukazuje, jak volat omezenou funkci z výrazu 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";
    }
}

Omezená funkce musí obsahovat restrict(amp) omezení popsaná v omezeních (C++ AMP) a splňovat je.

Viz také

C++ AMP (C++ Accelerated Massive Parallelism)
Syntaxe výrazů lambda
Volání funkcí
Objekty funkcí ve standardní knihovně C++
restrict (C++ AMP)