Partilhar via


Utilização de lambdas, objetos de função e funções restritas

O código C++ AMP que queres executar no acelerador é especificado como um argumento numa chamada ao parallel_for_each método. Pode fornecer uma expressão lambda ou um objeto de função (functor) como esse argumento. Adicionalmente, a expressão lambda ou o objeto função pode chamar uma função restrita a AMP em C++. Este tópico utiliza um algoritmo de adição de arrays para demonstrar lambdas, objetos de funções e funções restritas. O exemplo seguinte mostra o algoritmo sem código AMP em C++. São criadas duas matrizes unidimensionais de igual comprimento. Os elementos inteiros correspondentes são somados e armazenados numa terceira matriz unidimensional. O AMP C++ não é utilizado.

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 C++ AMP 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 de indexação e deve incluir restrict(amp). No exemplo, o objeto array_viewsum tem um posto de 1. Portanto, o parâmetro da afirmação lambda é um objeto índice que tem posto 1. Em tempo de execução, a expressão lambda é executada uma vez para cada elemento do objeto array_view . Para mais informações, consulte Sintaxe de Expressão Lambda.

Função Objeto

Podes fatorar o código do acelerador num 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 funcional deve incluir um construtor e deve incluir uma sobrecarga ao operador de chamada. O operador de chamada de função deve incluir um parâmetro de indexação. Uma instância do objeto de função é passada como segundo argumento ao método parallel_for_each . Neste exemplo, três objetos array_view são passados ao construtor de objetos de funções. O objetosum array_view tem uma classificação de 1. Portanto, o parâmetro do operador de chamada de função é um objeto índice que tem posto 1. Em tempo de execução, a função é executada uma vez para cada elemento do objeto array_view . Para mais informações, veja Chamada de Função e Objetos de Função na Biblioteca Padrão de C++.

Função restrita AMP em C++

Pode otimizar ainda mais o código acelerador criando uma função limitada e chamando-a a partir de uma expressão lambda ou de um objeto de função. O exemplo de código seguinte demonstra como chamar uma função restrita a partir 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)
        {
            AddElementsWithRestrictedFunction(idx, sum, a, b);
        });

    for (int i = 0; i <5; i++) {
        std::cout <<sum[i] <<"\n";
    }
}

A função restrita deve incluir restrict(amp) e conformar-se às restrições descritas em restringir (C++ AMP).

Consulte também

C++ AMP (paralelismo maciço acelerado em C++)
Sintaxe de Expressão Lambda
Chamada de Função
Objetos de Função na Biblioteca Padrão C++
restringir (C++ AMP)