Freigeben über


Verwenden von Lambdas, Funktionsobjekten und eingeschränkten Funktionen

Der C++ AMP-Code, den Sie auf dem Beschleuniger ausführen möchten, wird als Argument in einem Aufruf der parallel_for_each Methode angegeben. Sie können entweder einen Lambda-Ausdruck oder ein Funktionsobjekt (Functor) als dieses Argument bereitstellen. Darüber hinaus kann der Lambda-Ausdruck oder das Funktionsobjekt eine C++-AMP-eingeschränkte Funktion aufrufen. In diesem Thema wird ein Arrayzugabealgorithmus verwendet, um Lambdas, Funktionsobjekte und eingeschränkte Funktionen zu veranschaulichen. Das folgende Beispiel zeigt den Algorithmus ohne C++-AMP-Code. Es werden zwei 1dimensionale Arrays gleicher Länge erstellt. Die entsprechenden ganzzahligen Elemente werden in einem dritten 1-dimensionalen Array hinzugefügt und gespeichert. C++ AMP wird nicht verwendet.

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

Die Verwendung eines Lambda-Ausdrucks ist die direkteste Methode zum Umschreiben des Codes mit C++AMP.

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

Der Lambda-Ausdruck muss einen Indizierungsparameter enthalten und restrict(amp) umfassen. Im Beispiel hat das array_view-Objektsum den Rang 1. Daher ist der Parameter für die Lambda-Anweisung ein Indexobjekt mit Rang 1. Zur Laufzeit wird der Lambda-Ausdruck für jedes Element im array_view-Objekt einmal ausgeführt. Weitere Informationen finden Sie unter Lambda-Ausdruckssyntax.

Function-Objekt

Sie können den Beschleuniger-Code in ein Funktionsobjekt umwandeln.

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

Das Funktionsobjekt muss einen Konstruktor enthalten und eine Überladung des Funktionsaufrufoperators enthalten. Der Funktionsaufrufoperator muss einen Indizierungsparameter enthalten. Eine Instanz des Funktionsobjekts wird als zweites Argument an die parallel_for_each-Methode übergeben. In diesem Beispiel werden drei array_view Objekte an den Funktionsobjektkonstruktor übergeben. Das array_view-Objektsum hat den Rang 1. Daher ist der Parameter für den Funktionsaufrufoperator ein Indexobjekt mit Rang 1. Zur Laufzeit wird die Funktion für jedes Element im array_view-Objekt einmal ausgeführt. Weitere Informationen finden Sie unter Funktionsaufruf und Funktionsobjekte in der C++-Standardbibliothek.

C++-AMP-Restricted-Funktion

Sie können den Accelerator-Code weiter strukturieren, indem Sie eine eingeschränkte Funktion erstellen und sie aus einem Lambda-Ausdruck oder einem Funktionsobjekt aufrufen. Im folgenden Codebeispiel wird veranschaulicht, wie eine eingeschränkte Funktion aus einem Lambda-Ausdruck aufgerufen wird.

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

Die eingeschränkte Funktion muss die Einschränkungen enthalten restrict(amp) und einhalten, die in restrict (C++ AMP) beschrieben werden.

Siehe auch

C++ AMP (C++-Beschleunigter massiver Parallelismus)
Lambda-Ausdruckssyntax
Funktionsaufruf
Funktionsobjekte in der C++-Standardbibliothek
restrict (C++ AMP)