Aracılığıyla paylaş


UWP Uygulamalarında C++ AMP Kullanma

GPU (Grafik İşleme Birimi) veya diğer hesaplama hızlandırıcıları üzerinde hesaplamalar yapmak için Evrensel Windows Platformu (UWP) uygulamanızda 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 sarmalayıcı sağlamaz. Kodunuzda kendi oluşturduğunuz türler de dahil olmak üzere Windows Çalışma Zamanı türleri kullandığınızda, bunları C++ AMP ile uyumlu türlere dönüştürmeniz gerekir.

Not

C++ AMP üst bilgileri Visual Studio 2022 sürüm 17.0'dan itibaren kullanım dışı bırakılmıştır. Tüm AMP üst bilgileri dahil olmak derleme hataları oluşturur. Uyarıları susturmak için AMP üst bilgilerini eklemeden önce tanımlayın _SILENCE_AMP_DEPRECATION_WARNINGS .

Performans değerlendirmeleri

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ı kullanarak daha yüksek performans elde etmeye yardımcı olabilir çünkü hiçbir sıralama olması gerekmez.

C++ AMP çekirdeğinde, bu şekilde depolanan verilere erişmek için veya dizi depolama alanını std::vector 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 sıralama

Windows Çalışma Zamanı API'lerle çalışırken, ref anahtar sözcüğü veya değerPlatform::Array<T>^kullanılarak bildirilen sınıflar veya yapılar gibi karmaşık veri türleri gibi Windows Çalışma Zamanı bir kapsayıcıda 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

ve Platform::Array<T>^ T bir POD türüyle karşılaştığınızda, yalnızca üye işlevini kullanarak temel alınan depolamaya get 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: ref 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 bir hazırlama dizisiconcurrency::arrayperformansı 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 bkz.

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