Compartir a través de


Usar expresiones lambda, objetos de función y funciones restringidas

El código de C++ AMP que desea ejecutar en el acelerador se especifica como argumento en una llamada al parallel_for_each método . Puede proporcionar una expresión lambda o un objeto de función (functor) como un argumento. Además, la expresión lambda o el objeto de función pueden llamar a una función con restricción AMP de C++. En este tema se usa un algoritmo de suma de matriz para mostrar expresiones lambda, objetos de función y funciones restringidas. En el ejemplo siguiente se muestra el algoritmo sin código C++ AMP. Se crean dos matrices unidimensionales de la misma longitud. Los elementos enteros correspondientes se agregan y almacenan en una tercera matriz unidimensional. No se usa C++ AMP.

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

Expresión lambda

El uso de una expresión lambda es la manera más directa de usar C++ AMP para reescribir el código.

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

La expresión lambda debe incluir un parámetro de indexación y restrict(amp). En el ejemplo, el objeto array_viewsum tiene un rango de 1. Por lo tanto, el parámetro de la instrucción lambda es un objeto de índice que tiene el rango 1. En tiempo de ejecución, la expresión lambda se ejecuta una vez para cada elemento del objeto array_view. Para obtener más información, vea Sintaxis de la expresión lambda.

Function (Objeto)

Puede factorizar el código del acelerador en un objeto de función.

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

El objeto de función debe incluir un constructor y una sobrecarga del operador de llamada de función. El operador de llamada de función debe incluir un parámetro de indexación. Una instancia del objeto de función se pasa como el segundo argumento al método parallel_for_each. En este ejemplo, se pasan tres objetos array_view al constructor de objetos de función. El objeto array_view sum tiene un rango de 1. Por lo tanto, el parámetro para el operador de llamada de función es un objeto de índice que tiene el rango 1. En tiempo de ejecución, la expresión lambda se ejecuta una vez para cada elemento en el objeto array_view. Para obtener más información, vea Llamada de función y Objetos de función en la biblioteca estándar de C++.

Función con restricción amp de C++

Puede factorizar aún más el código del acelerador creando una función restringida y llamándola desde una expresión lambda o un objeto de función. En el ejemplo de código siguiente se muestra cómo llamar a una función restringida desde una expresión 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 función restringida debe incluir restrict(amp) y cumplir las restricciones que se describen en restrict (C++ AMP).

Consulte también

C++ AMP (C++ Accelerated Massive Parallelism)
Sintaxis de la expresión lambda
Llamada a función
Objetos de función en la biblioteca estándar de C++
restrict (C++ AMP)