Partager via


Utilisation de fonctions lambda, d'objets de fonctions et de fonctions restreintes

Le code AMP C++ que vous souhaitez exécuter sur l’accélérateur est spécifié en tant qu’argument dans un appel à la parallel_for_each méthode. Vous pouvez fournir une expression lambda ou un objet de fonction (fonctor) comme argument. En outre, l’expression lambda ou l’objet de fonction peut appeler une fonction AMP C++. Cette rubrique utilise un algorithme d’ajout de tableau pour illustrer les fonctions lambda, les objets de fonction et les fonctions restreintes. L’exemple suivant montre l’algorithme sans code AMP C++. Deux tableaux 1 dimensionnels de longueur égale sont créés. Les éléments entiers correspondants sont ajoutés et stockés dans un troisième tableau 1 dimensionnel. L’AMP C++ n’est pas utilisé.

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 Expression

L’utilisation d’une expression lambda est le moyen le plus direct d’utiliser C++ AMP pour réécrire le code.

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’expression lambda doit inclure un paramètre d’indexation et doit inclure restrict(amp). Dans l’exemple, l’objet array_viewsum a un rang de 1. Par conséquent, le paramètre de l’instruction lambda est un objet d’index qui a le rang 1. Au moment de l’exécution, l’expression lambda est exécutée une fois pour chaque élément de l’objet array_view. Pour plus d’informations, consultez Syntaxe d’expression lambda.

Objet de function

Vous pouvez factoriser le code accélérateur dans un objet de fonction.

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’objet de fonction doit inclure un constructeur et doit inclure une surcharge de l’opérateur d’appel de fonction. L’opérateur d’appel de fonction doit inclure un paramètre d’indexation. Une instance de l’objet de fonction est passée en tant que deuxième argument à la méthode parallel_for_each . Dans cet exemple, trois objets array_view sont passés au constructeur d’objet de fonction. L’objet sum array_view a un rang de 1. Par conséquent, le paramètre de l’opérateur d’appel de fonction est un objet d’index qui a le rang 1. Au moment de l’exécution, la fonction est exécutée une fois pour chaque élément de l’objet array_view. Pour plus d’informations, consultez Les objets d’appel de fonction et de fonction dans la bibliothèque standard C++.

C++ AMP-Restricted, fonction

Vous pouvez ajouter un facteur supplémentaire au code accélérateur en créant une fonction restreinte et en l’appelant à partir d’une expression lambda ou d’un objet de fonction. L’exemple de code suivant montre comment appeler une fonction restreinte à partir d’une expression 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 fonction restreinte doit inclure restrict(amp) et se conformer aux restrictions décrites dans la restriction (AMP C++).

Voir aussi

C++ AMP (C++ Accelerated Massive Parallelism)
Syntaxe d’expression lambda
Appel de fonction
Objets de fonction dans la bibliothèque standard C++
restrict (C++ AMP)