Aracılığıyla paylaş


UWP Uygulamalarında C++ AMP Kullanma

Evrensel Windows Platformu (UWP) uygulamanızda GPU (Grafik İşleme Birimi) veya diğer hesaplama hızlandırıcıları üzerinde hesaplamalar yapmak için C++ AMP (C++ Hızlandırılmış Büyük Paralellik) kullanabilirsiniz. Ancak, C++ AMP doğrudan Windows Çalışma Zamanı türleriyle çalışmak için API'ler sağlamaz ve Windows Çalışma Zamanı C++ AMP için bir sarmalayıcı sağlamaz. Kendi oluşturduğunuz türler de dahil olmak üzere kodunuzda Windows Çalışma Zamanı türlerini kullandığınızda, bunları C++ AMP ile uyumlu türlere dönüştürmeniz gerekir.

Uyarı

C++ AMP üst bilgileri Visual Studio 2022 sürüm 17.0'dan itibaren kullanım dışı bırakılmıştır. AMP üst bilgilerini dahil etmek derleme hatalarına neden olur. AMP üst bilgilerini eklemeden önce uyarıları susturmak için _SILENCE_AMP_DEPRECATION_WARNINGS tanımla.

Performansla ilgili dikkat edilmesi gerekenler

Evrensel Windows Platformu (UWP) uygulamanızı oluşturmak için Visual C++ bileşen uzantıları C++/CX kullanıyorsanız, C++ AMP ile kullanılacak veriler için bitişik depolama ile (örneğin, std::vector C stili diziler) düz eski veri (POD) türlerini birlikte kullanmanızı öneririz. Bu, POD olmayan türleri veya Windows Çalışma Zamanı kapsayıcılarını kullandığınızdan daha yüksek performans elde etmeye yardımcı olabilir çünkü hazırlama işlemi gerekmez.

C++ AMP çekirdeğinde, bu şekilde depolanan verilere erişmek için, std::vector veya dizi depolama alanını bir concurrency::array_view içinde sarmalayın ve ardından dizi görünümünü bir concurrency::parallel_for_each döngüde kullanın.

// simple vector addition example
std::vector<int> data0(1024, 1);
std::vector<int> data1(1024, 2);
std::vector<int> data_out(data0.size(), 0);

concurrency::array_view<int, 1> av0(data0.size(), data0);
concurrency::array_view<int, 1> av1(data1.size(), data1);
concurrency::array_view<int, 1> av2(data_out.size(), data2);

av2.discard_data();

concurrency::parallel_for_each(av0.extent, [=](concurrency::index<1> idx) restrict(amp)
    {
        av2[idx] = av0[idx] + av1[idx];
    });

Windows Çalışma Zamanı türlerini hazırlama

Windows Çalışma Zamanı API'leriyle çalışırken, Platform::Array<T>^ anahtar sözcüğü veya değer anahtar sözcüğü kullanılarak bildirilen sınıflar veya yapılar gibi karmaşık veri türleri gibi bir Windows Çalışma Zamanı kapsayıcısında depolanan veriler üzerinde C++ AMP kullanmak isteyebilirsiniz. Bu gibi durumlarda, verileri C++ AMP'nin kullanımına açmak için bazı ek çalışmalar yapmanız gerekir.

Platform::Dizi<T>^, burada T bir POD türüdür

Platform::Array<T>^ ile karşılaştığınızda ve T bir POD türü ise, yalnızca get üye işlevini kullanarak temel depolamaya erişebilirsiniz.

Platform::Array<float>^ arr; // Assume that this was returned by a Windows Runtime API
concurrency::array_view<float, 1> av(arr->Length, &arr->get(0));

T bir POD türü değilse, verileri C++ AMP ile kullanmak için aşağıdaki bölümde açıklanan tekniği kullanın.

Windows Çalışma Zamanı türleri: başvuru sınıfları ve değer sınıfları

C++ AMP karmaşık veri türlerini desteklemez. Buna POD olmayan türler ve ref anahtar sözcüğü veya değer anahtar sözcüğü kullanılarak bildirilen türler dahildir. Bir bağlamda desteklenmeyen bir restrict(amp) tür kullanılırsa, derleme zamanı hatası oluşturulur.

Desteklenmeyen bir türle karşılaştığınızda, verilerinin ilginç bölümlerini bir concurrency::array nesneye kopyalayabilirsiniz. Bu el ile kopyalama yaklaşımı, verileri C++ AMP tarafından kullanılabilir hale getirmenin yanı sıra, veri yerelliğini en üst düzeye çıkararak ve kullanılmayacak verilerin hızlandırıcıya kopyalanmadığından emin olarak performansı artırabilir. AMP çalışma zamanına dizinin belirtilen hızlandırıcıdaki diğer diziler arasında sık aktarım için iyileştirilmesi gerektiğine dair bir ipucu sağlayan özel bir biçimi olan concurrency::array kullanarak performansı daha da geliştirebilirsiniz.

// pixel_color.h
ref class pixel_color sealed
{
public:
    pixel_color(Platform::String^ color_name, int red, int green, int blue)
    {
        name = color_name;
        r = red;
        g = green;
        b = blue;
    }

    property Platform::String^ name;
    property int r;
    property int g;
    property int b;
};

// Some other file

std::vector<pixel_color^> pixels (256);

for (pixel_color ^pixel : pixels)
{
    pixels.push_back(ref new pixel_color("blue", 0, 0, 255));
}

// Create the accelerators
auto cpuAccelerator = concurrency::accelerator(concurrency::accelerator::cpu_accelerator);
auto devAccelerator = concurrency::accelerator(concurrency::accelerator::default_accelerator);

// Create the staging arrays
concurrency::array<float, 1> red_vec(256, cpuAccelerator.default_view, devAccelerator.default_view);
concurrency::array<float, 1>  blue_vec(256, cpuAccelerator.default_view, devAccelerator.default_view);

// Extract data from the complex array of structs into staging arrays.
concurrency::parallel_for(0, 256, [&](int i)
    {
        red_vec[i] = pixels[i]->r;
        blue_vec[i] = pixels[i]->b;
    });

// Array views are still used to copy data to the accelerator
concurrency::array_view<float, 1> av_red(red_vec);
concurrency::array_view<float, 1> av_blue(blue_vec);

// Change all pixels from blue to red.
concurrency::parallel_for_each(av_red.extent, [=](index<1> idx) restrict(amp)
    {
        av_red[idx] = 255;
        av_blue[idx] = 0;
    });

Ayrıca bakınız

C++ kullanarak ilk UWP uygulamanızı oluşturma
C++ uygulamasında Windows Çalışma Zamanı Bileşenleri Oluşturma