Partilhar via


Usar Lambdas, objetos de função e funções restritas

O código de AMP C++ que você deseja executar no acelerador é especificado como um argumento na chamada ao método parallel_for_each.Você pode fornecer uma expressão lambda ou um objeto de função (functor) como o argumento.Além de isso, a expressão lambda ou objeto de função podem chamar a função restrita C++ Amp.Este tópico usa um algoritmo de adição de matriz para demonstrar lambdas, objetos de função e funções restritas.O exemplo a seguir mostra o algoritmo sem código de AMP C++.São criadas duas matrizes unidimensionais de tamanho igual.Os elementos inteiros correspondentes são adicionados e armazenados em uma terceira matriz unidimensional.O AMP C++ não é usado.

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

Expressão lambda

Usar uma expressão lambda é a forma mais direta de usar o AMP C++ para reescrever o 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";
    }
}

A expressão lambda deve incluir um parâmetro indexação e deve incluir restrict(amp).No exemplo, o objeto array_viewsum tem classificação 1.Portanto, o parâmetro para a instrução lambda é um objeto índice que possui a posição 1.Em tempo de execução, a expressão lambda é executada uma vez para cada elemento no objeto array_view.Para obter mais informações, consulte Sintaxe de expressões lambda.

Objeto de função

Você pode incluir o código de aceleradores em um objeto de função.

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

O objeto de função deve incluir um construtor e deve incluir uma sobrecarga do operador de chamada de função.O operador de chamada de função deve incluir um parâmetro indexação.Uma instância do objeto de função é passado como o segundo argumento para o método parallel_for_each.Nesse exemplo, três objetos array_view são passados para o construtor do objeto de função.O objeto sumarray_view tem classificação 1.Portanto, o parâmetro para o operador de chamada de função é um objeto índice que possui a posição 1.Em tempo de execução, a função é executada uma vez para cada elemento no objeto array_view.Para obter mais informações, consulte Chamada de função (C++) e Function Objects.

Função restrita AMP C++

Você ainda pode incluir o código de aceleradores criando uma função restrita e chamando-a a partir de uma expressão lambda ou de um objeto de função.O exemplo de código a seguir demonstra como chamar uma função estritamente de uma expressão 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";
    }
}

A função estritamente deve incluir restrict(amp) e estar de acordo com as restrições que são descritas em Cláusula de restrição (AMP C++).

Consulte também

Referência

Sintaxe de expressões lambda

Chamada de função (C++)

Cláusula de restrição (AMP C++)

Conceitos

Function Objects

Outros recursos

AMP C++ (C++ acelerado paralelismo maciço)