Condividi tramite


Utilizzo di espressioni lambda, oggetti funzione e funzioni con restrizioni

Il codice C++ AMP da eseguire sull'acceleratore viene specificato come argomento in una chiamata al parallel_for_each metodo . È possibile specificare un'espressione lambda o un oggetto funzione (functor) come argomento. Inoltre, l'espressione lambda o l'oggetto funzione possono chiamare una funzione con restrizioni AMP C++. In questo argomento viene usato un algoritmo di addizione di matrici per illustrare espressioni lambda, oggetti funzione e funzioni con restrizioni. L'esempio seguente mostra l'algoritmo senza codice AMP C++. Vengono create due matrici bidimensionali di lunghezza uguale. Gli elementi integer corrispondenti vengono aggiunti e archiviati in una terza matrice dimensionale. C++ AMP non viene usato.

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

Espressione lambda

L'uso di un'espressione lambda è il modo più diretto per usare C++ AMP per riscrivere il codice.

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

L'espressione lambda deve includere un parametro di indicizzazione e deve includere restrict(amp). Nell'esempio l'oggetto array_viewsum ha un rango pari a 1. Di conseguenza, il parametro dell'istruzione lambda è un oggetto indice con classificazione 1. In fase di esecuzione, l'espressione lambda viene eseguita una volta per ogni elemento nell'oggetto array_view . Per altre informazioni, vedere Sintassi delle espressioni lambda.

Oggetto Function

È possibile inserire il codice dell'acceleratore in un oggetto funzione.

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

L'oggetto funzione deve includere un costruttore e deve includere un overload dell'operatore di chiamata di funzione. L'operatore di chiamata di funzione deve includere un parametro di indicizzazione. Un'istanza dell'oggetto funzione viene passata come secondo argomento al metodo parallel_for_each . In questo esempio vengono passati tre oggetti array_view al costruttore dell'oggetto funzione. L'oggetto sum array_view ha un rango pari a 1. Di conseguenza, il parametro dell'operatore di chiamata di funzione è un oggetto index con classificazione 1. In fase di esecuzione, la funzione viene eseguita una volta per ogni elemento nell'oggetto array_view . Per altre informazioni, vedere Chiamata di funzione e oggetti funzione nella libreria standard C++.

Funzione C++ AMP con restrizioni

È possibile prendere in considerazione ulteriormente il codice dell'acceleratore creando una funzione con restrizioni e chiamandola da un'espressione lambda o da un oggetto funzione. Nell'esempio di codice seguente viene illustrato come chiamare una funzione con restrizioni da un'espressione 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";
    }
}

La funzione con restrizioni deve includere restrict(amp) ed essere conforme alle restrizioni descritte in Restrict (C++ AMP).

Vedi anche

C++ AMP (C++ Accelerated Massive Parallelism)
Sintassi delle espressioni lambda
Chiamata di funzione
Oggetti funzione della libreria standard C++
restrict (C++ AMP)