Dela via


Använda Lambdas, funktionsobjekt och begränsade funktioner

C++ AMP-koden som du vill köra på acceleratorn anges som ett argument i ett anrop till parallel_for_each metoden. Du kan ange antingen ett lambda-uttryck eller ett funktionsobjekt (functor) som argument. Dessutom kan lambda-uttrycket eller funktionsobjektet anropa en C++ AMP-begränsad funktion. Det här avsnittet använder en matristilläggsalgoritm för att demonstrera lambdas, funktionsobjekt och begränsade funktioner. I följande exempel visas algoritmen utan C++ AMP-kod. Två 1-dimensionella matriser med samma längd skapas. Motsvarande heltalselement läggs till och lagras i en tredje 1-dimensionell matris. C++ AMP används inte.

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-uttryck

Att använda ett lambda-uttryck är det mest direkta sättet att använda C++ AMP för att skriva om koden.

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-uttrycket måste innehålla en indexeringsparameter och måste innehålla restrict(amp). I exemplet har array_view-objektetsum rangordningen 1. Därför är parametern till lambda-instruktionen ett indexobjekt som har rangordning 1. När programmet körs körs lambda-uttrycket en gång för varje element i array_view-objektet. Mer information finns i Lambda-uttryckssyntax.

Funktionsobjekt

Du kan dela in acceleratorkoden i ett funktionsobjekt.

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

Funktionsobjektet måste innehålla en konstruktor och måste innehålla en överlagring av funktionsanropsoperatorn. Funktionsanropsoperatorn måste innehålla en indexeringsparameter. En instans av funktionsobjektet skickas som det andra argumentet till metoden parallel_for_each . I det här exemplet skickas tre array_view objekt till funktionsobjektkonstruktorn. Objektet array_viewsum har rangordningen 1. Därför är parametern för funktionsanropsoperatorn ett indexobjekt som har rangordning 1. Under körning körs funktionen en gång för varje element i array_view-objektet. Mer information finns i Funktionsanrop och Funktionsobjekt i C++-standardbiblioteket.

C++ AMP-Restricted-funktion

Du kan ytterligare ta hänsyn till acceleratorkoden genom att skapa en begränsad funktion och anropa den från ett lambda-uttryck eller ett funktionsobjekt. Följande kodexempel visar hur du anropar en begränsad funktion från ett lambda-uttryck.

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

Den begränsade funktionen måste inkludera restrict(amp) och följa de begränsningar som beskrivs i begränsa (C++ AMP).

Se även

C++ AMP (C++ Accelererad massiv parallellitet)
Lambda-uttryckssyntax
Funktionsanrop
Funktionsobjekt i C++-standardbiblioteket
begränsa (C++ AMP)