Compartir a través de


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

El código AMP de C++ que se desea ejecutar en el acelerador se especifica como un argumento en una llamada al método parallel_for_each.Puede proporcionar o bien una expresión lambda o un objeto de función (functor) como argumento.Además, la expresión lambda o el objeto de función pueden llamar a un AMP de C++ con función restringida.Este tema utiliza un algoritmo de suma de vectores para demostrar las expresiones lambda, los objetos de función y las funciones restringidas.El siguiente ejemplo muestra el algoritmo sin código de C++ AMP.Se crean dos vectores unidimensionales de igual longitud.Los elementos enteros correspondientes se agregan y se almacenan en un tercera vector unidimensional.No se utiliza 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

Emplear una expresión lambda es la manera más directa de utilizar 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 debe incluir restrict(amp).En el ejemplo, el objeto array_viewsum tiene un rango de 1.Por tanto, el parámetro de la expresión lambda es un objeto índice que tiene rango 1.En tiempo de ejecución, la expresión lambda se ejecuta una vez por cada elemento en el 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 función debe incluir un constructor y también una sobrecarga del operador de llamada a función.El operador de llamada a la función debe incluir un parámetro de indexación.Una instancia del objeto función se pasa como segundo argumento al método parallel_for_each.En este ejemplo, se pasan tres objetos array_view al constructor del objeto función.El objeto array_viewsum tiene un rango de 1.Por lo tanto, el parámetro del operador de llamada a función es un objeto índice que tiene rango 1.En tiempo de ejecución, la función se ejecuta una vez por cada elemento en el objeto array_view.Para obtener más información, vea Llamada a función (C++) y Objetos de función.

Función restringida del Amp de C++

Puede factorizar el código del acelerador mediante la creación de una función restringida y llamarlo a partir de una expresión lambda o un objeto función.El siguiente código de ejemplo 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)
        {
            AddElements(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 se ajustan a las restricciones que se describen en Cláusula de restricción (AMP de C++).

Vea también

Referencia

Sintaxis de la expresión lambda

Llamada a función (C++)

Cláusula de restricción (AMP de C++)

Conceptos

Objetos de función

Otros recursos

C++ AMP (C++ Accelerated Massive Parallelism)