Bagikan melalui


Menggunakan Lambda, Objek Fungsi, dan Fungsi Terbatas

Kode AMP C++ yang ingin Anda jalankan pada akselerator ditentukan sebagai argumen dalam panggilan ke parallel_for_each metode . Anda dapat menyediakan ekspresi lambda atau objek fungsi (functor) sebagai argumen tersebut. Selain itu, ekspresi lambda atau objek fungsi dapat memanggil fungsi yang dibatasi AMP C++. Topik ini menggunakan algoritma penambahan array untuk menunjukkan lambda, objek fungsi, dan fungsi terbatas. Contoh berikut menunjukkan algoritma tanpa kode AMP C++. Dua array 1 dimensi dengan panjang yang sama dibuat. Elemen bilangan bulat yang sesuai ditambahkan dan disimpan dalam array 1 dimensi ketiga. C++ AMP tidak digunakan.

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

Ekspresi Lambda

Menggunakan ekspresi lambda adalah cara paling langsung untuk menggunakan C++ AMP untuk menulis ulang kode.

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

Ekspresi lambda harus menyertakan satu parameter pengindeksan dan harus menyertakan restrict(amp). Dalam contoh, objek array_viewsum memiliki peringkat 1. Oleh karena itu, parameter untuk pernyataan lambda adalah objek indeks yang memiliki peringkat 1. Pada runtime, ekspresi lambda dijalankan sekali untuk setiap elemen dalam objek array_view . Untuk informasi selengkapnya, lihat Sintaks Ekspresi Lambda.

Objek Fungsi

Anda dapat memperhitungkan kode akselerator ke dalam objek fungsi.

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

Objek fungsi harus menyertakan konstruktor dan harus menyertakan kelebihan beban operator panggilan fungsi. Operator panggilan fungsi harus menyertakan satu parameter pengindeksan. Instans objek fungsi diteruskan sebagai argumen kedua ke metode parallel_for_each . Dalam contoh ini, tiga objek array_view diteruskan ke konstruktor objek fungsi. Objek array_viewsum memiliki peringkat 1. Oleh karena itu, parameter ke operator panggilan fungsi adalah objek indeks yang memiliki peringkat 1. Pada runtime, fungsi dijalankan sekali untuk setiap elemen dalam objek array_view . Untuk informasi selengkapnya, lihat Panggilan Fungsi dan Objek Fungsi di Pustaka Standar C++.

Fungsi C++ AMP-Restricted

Anda dapat memperhitungkan lebih lanjut kode akselerator dengan membuat fungsi terbatas dan memanggilnya dari ekspresi lambda atau objek fungsi. Contoh kode berikut menunjukkan cara memanggil fungsi terbatas dari ekspresi 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";
    }
}

Fungsi terbatas harus menyertakan restrict(amp) dan sesuai dengan batasan yang dijelaskan dalam batasan (C++ AMP).

Lihat juga

C++ AMP (C++ Paralelisme Masif Dipercepat)
Sintaks Ekspresi Lambda
Panggilan Fungsi
Objek Fungsi di Pustaka Standar C++
batasi (C++ AMP)