Używanie wyrażeń lambda, obiektów Function i funkcji z ograniczeniami

Kod C++ AMP, który chcesz uruchomić w akceleratorze, jest określony jako argument w wywołaniu parallel_for_each metody . Jako argument można podać wyrażenie lambda lub obiekt funkcji (functor). Ponadto wyrażenie lambda lub obiekt funkcji mogą wywoływać funkcję z ograniczeniami języka C++AMP. W tym temacie użyto algorytmu dodawania tablicy w celu zademonstrowania funkcji lambda, obiektów funkcji i funkcji ograniczonych. W poniższym przykładzie przedstawiono algorytm bez kodu C++ AMP. Tworzone są dwie tablice 1-wymiarowe o równej długości. Odpowiednie elementy całkowite są dodawane i przechowywane w trzeciej tablicy 1-wymiarowej. Język C++ AMP nie jest używany.

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

Wyrażenie lambda

Użycie wyrażenia lambda to najbardziej bezpośredni sposób użycia języka C++ AMP do ponownego zapisania kodu.

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

Wyrażenie lambda musi zawierać jeden parametr indeksowania i musi zawierać wartość restrict(amp). W tym przykładzie obiekt array_viewsum ma rangę 1. W związku z tym parametr instrukcji lambda jest obiektem indeksu, który ma rangę 1. W czasie wykonywania wyrażenie lambda jest wykonywane raz dla każdego elementu w obiekcie array_view . Aby uzyskać więcej informacji, zobacz Składnia wyrażeń lambda.

Obiekt Function

Kod akceleratora można uwzględnić w obiekcie funkcji.

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

Obiekt funkcji musi zawierać konstruktor i musi zawierać przeciążenie operatora wywołania funkcji. Operator wywołania funkcji musi zawierać jeden parametr indeksowania. Wystąpienie obiektu funkcji jest przekazywane jako drugi argument do metody parallel_for_each . W tym przykładzie trzy obiekty array_view są przekazywane do konstruktora obiektu funkcji. Obiekt sum array_view ma rangę 1. W związku z tym parametr operatora wywołania funkcji jest obiektem indeksu, który ma rangę 1. W czasie wykonywania funkcja jest wykonywana raz dla każdego elementu w obiekcie array_view . Aby uzyskać więcej informacji, zobacz Wywołanie funkcji i obiekty funkcji w standardowej bibliotece języka C++.

C++ AMP-Restricted, funkcja

Kod akceleratora można dodatkowo uwzględnić, tworząc funkcję z ograniczeniami i wywołując ją z wyrażenia lambda lub obiektu funkcji. W poniższym przykładzie kodu pokazano, jak wywołać funkcję ograniczoną z wyrażenia 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";
    }
}

Funkcja ograniczona musi zawierać restrict(amp) ograniczenia opisane w temacie ograniczeń (C++ AMP) i być zgodne z ograniczeniami.

Zobacz też

C++ AMP (C++ Accelerated Massive Parallelism)
Składnia wyrażenia lambda
Wywołanie funkcji
Obiekty funkcji w standardowej bibliotece C++
ograniczenie (C++ AMP)