Udostępnij za pośrednictwem


Korzystanie z funkcji obiektów, ograniczeniami funkcji i Lambdas

Kod C++ AMP, który chcesz uruchomić na akceleratorze jest określony jako argument w wywołaniu metody parallel_for_each.Argument ten można dostarczyć za pomocą wyrażenia lambda lub obiektu funkcyjnego (funktora).Ponadto wyrażenie lambda lub obiekt funkcyjny może wywołać funkcję C++ AMP z ograniczeniami.W tym temacie korzysta się z algorytmu dodawania tablic do zademonstrowania wyrażeń lambda, obiektów funkcyjnych i funkcji z ograniczeniami.W poniższym przykładzie pokazany jest algorytm bez kodu C++ AMP.Tworzone są dwie tablice 1-wymiarowe równej długości.Odpowiadające elementy całkowite są dodawane i przechowywane w trzeciej 1-wymiarowej tablicy.C++ AMP nie jest używane.

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 jest najbardziej bezpośrednim sposobem wykorzystania C++ AMP do przepisania 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ć restrict(amp).Na przykład obiekt sum z array_view ma 1 wymiar.Dlatego parametr do instrukcji lambda jest obiektem index o jednym wymiarze.W czasie wykonywania, wyrażenie lambda jest wykonywane raz dla każdego elementu w obiekcie array_view.Aby uzyskać więcej informacji, zobacz Składni wyrażenia lambda.

Obiekt funkcyjny

Można przekazać kod akceleratora do obiektu funkcyjnego.

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 funkcyjny musi zawierać konstruktor i przeciążenie operatora wywołania funkcji.Operator wywołania funkcji musi zawierać jeden parametr indeksowania.Wystąpienie obiektu funkcyjnego jest przekazywane jako drugi argument do metody parallel_for_each.W tym przykładzie trzy obiekty array_view są przekazywane do funkcji konstruktora obiektu.Obiekt sum z array_view ma 1 wymiar.Dlatego parametr operatora wywołania funkcji jest obiektem index o wymiarze równym 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 (C++) i Funkcja obiektów.

Funkcja C++ AMP z ograniczeniami

Można przekazać kod akceleratora tworząc funkcję z ograniczeniami i wywołując ją w wyrażeniu lambda lub w obiekcie funkcyjnym.Poniższy przykład kodu pokazuje sposób wywołania funkcji z ograniczeniami 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)
        {
            AddElements(idx, sum, a, b);
        }
    );

    for (int i = 0; i < 5; i++) {
        std::cout << sum[i] << "\n";
    }
}

Funkcja z ograniczeniami musi zawierać restrict(amp) i być zgodna z ograniczeniami, które są opisane w Klauzula ograniczenia (C++ AMP).

Zobacz też

Informacje

Składni wyrażenia lambda

Wywołanie funkcji (C++)

Klauzula ograniczenia (C++ AMP)

Koncepcje

Funkcja obiektów

Inne zasoby

C++ AMP (C++ przyspieszyć równoległości prostych masowe)