Aracılığıyla paylaş


Lambda'lar, İşlev Nesneleri ve Kısıtlanmış İşlevler Kullanma

Hızlandırıcıda çalıştırmak istediğiniz C++ AMP kodu, yöntemine parallel_for_each yapılan bir çağrıda bağımsız değişken olarak belirtilir. Bu bağımsız değişken olarak bir lambda ifadesi veya işlev nesnesi (functor) sağlayabilirsiniz. Ayrıca lambda ifadesi veya işlev nesnesi C++ AMP kısıtlanmış işlevini çağırabilir. Bu konu lambdaları, işlev nesnelerini ve kısıtlanmış işlevleri göstermek için bir dizi ekleme algoritması kullanır. Aşağıdaki örnekte C++ AMP kodu olmayan algoritma gösterilmektedir. Eşit uzunlukta iki 1 boyutlu dizi oluşturulur. Karşılık gelen tamsayı öğeleri eklenir ve üçüncü bir 1 boyutlu dizide depolanır. C++ AMP kullanılmaz.

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

Lambda İfadesi

Lambda ifadesi kullanmak, kodu yeniden yazmak için C++ AMP kullanmanın en doğrudan yoludur.

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

Lambda ifadesi bir dizinleme parametresi içermeli ve içermelidir restrict(amp). Örnekte, array_viewsum nesnesi 1 derecesine sahiptir. Bu nedenle, lambda deyiminin parametresi 1 derecesine sahip bir dizin nesnesidir. Çalışma zamanında, lambda ifadesi array_view nesnesindeki her öğe için bir kez yürütülür. Daha fazla bilgi için bkz . Lambda İfade söz dizimi.

İşlev Nesnesi

Hızlandırıcı kodunu bir işlev nesnesi olarak hesaba katabilirsiniz.

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

İşlev nesnesi bir oluşturucu içermeli ve işlev çağrısı işlecinin aşırı yüklemesini içermelidir. İşlev çağrısı işleci bir dizinleme parametresi içermelidir. İşlev nesnesinin bir örneği, parallel_for_each yöntemine ikinci bağımsız değişken olarak geçirilir. Bu örnekte, işlev nesnesi oluşturucusunda üç array_view nesnesi geçirilir. array_view nesnesi sum 1 derecesine sahiptir. Bu nedenle, işlev çağrısı işleci parametresi 1 derecesine sahip bir dizin nesnesidir. Çalışma zamanında işlev, array_view nesnesindeki her öğe için bir kez yürütülür. Daha fazla bilgi için bkz. C++ Standart Kitaplığı'nda İşlev Çağrısı ve İşlev Nesneleri.

C++ AMP Kısıtlı İşlevi

Kısıtlanmış bir işlev oluşturup bunu bir lambda ifadesinden veya işlev nesnesinden çağırarak hızlandırıcı kodunu daha fazla faktöre dönüştürebilirsiniz. Aşağıdaki kod örneği, bir lambda ifadesinden kısıtlı bir işlevin nasıl çağrılduğunu gösterir.

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

Kısıtlanmış işlevin restrict (C++ AMP)restrict(amp)açıklanan kısıtlamaları içermesi ve bunlara uyması gerekir.

Ayrıca bkz.

C++ AMP (C++ Hızlandırılmış Yüksek Paralellik)
Lambda İfadesi Söz Dizimi
İşlev Çağrısı
C++ Standart Kitaplığındaki İşlev Nesneleri
restrict (C++ AMP)