Udostępnij za pośrednictwem


Korzystanie z C++ AMP w aplikacjach sklepu Windows Store

Można użyć C++ AMP (C++ Accelerated Massive Parallelism) w aplikacji Windows Store w celu wykonania obliczeń na procesorze graficznym (GPU) lub innych akceleratorach obliczeniowych.Jednak C++ AMP nie zapewnia interfejsu API do pracy bezpośrednio z typami środowiska wykonawczego systemu Windows, a środowisko wykonawcze systemu Windows nie zapewnia otoki dla C++ AMP.Kiedy używasz typów środowiska wykonawczego systemu Windows w swoim kodzie — włączając te, utworzone przez Ciebie — musisz konwertować je na typy, które są kompatybilne z C++ AMP.

Zagadnienia dotyczące wydajności

Jeśli używasz Rozszerzenia składników dla programu Visual C++ (C++/CX) do tworzenia aplikacji Windows Store, zalecamy użycie typów starych-prostych-danych (POD) wraz z ciągłym magazynowaniem — na przykład, std::vector lub tabeli stylu C — dla danych, które będą używane z C++ AMP.Może Ci to pomóc w osiągnięciu większej wydajności niż przy użyciu typów non-POD lub kontenerów Windows RT, ponieważ nie musi występować szeregowanie.

W jądrze C++ AMP, aby uzyskać dostęp do danych przechowywanych w ten sposób, należy po prostu zawinąć std::vector lub magazyn tablic w concurrency::array_view, a następnie użyć widoku tablicy w pętli concurrency::parallel_for_each:

// 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];
});

Szeregowanie typów środowiska wykonawczego systemu Windows

Podczas pracy z interfejsami API środowiska wykonawczego systemu Windows, warto używać C++ AMP na danych przechowywanych w kontenerze środowiska wykonawczego systemu Windows takich jak Platform::Array<T>^ lub złożonych typach danych takich jak klasy lub struktury, które są zadeklarowane za pomocą słowa kluczowego ref lub słowa kluczowego value.W takich sytuacjach należy wykonać dodatkową pracę, aby udostępnić dane C++ AMP.

Wykonaj::Tablicę y&lt;T&gt;^, gdzie T jest typem POD

Jeśli pojawił się Platform::Array<T>^ i T jest typem POD, do jego podstawowej magazynu można uzyskać dostęp tylko za pomocą get funkcji składowej:

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));

Jeśli T nie jest typem POD, użyj metody opisanej w poniższej sekcji, aby używać danych z C++ AMP.

Typy środowiska wykonawczego systemu Windows: klasy odniesienia i klasy wartości

Wzmacniacz C++ nie obsługuje złożonych typów danych.Obejmuje to typy non-POD i wszystkie typy, które są zdeklarowane z użyciem słowa kluczowego ref lub słowa kluczowego value.Jeśli nieobsługiwany typ zostanie użyty w kontekście restrict(amp), zostanie wygenerowany błąd kompilacji.

Kiedy napotykasz nieobsługiwany typ, możesz skopiować interesujące części jego danych do obiektu concurrency::array.Oprócz udostępnienia danych dla języka C++ AMP do konsumpcji, to podejście ręcznego kopiowania może również ulepszyć wydajność maksymalizując miejscowość danych i zapewniając, że dane, które nie będą używane nie zostaną skopiowane do akceleratora.Możesz podnieść wydajność jeszcze bardziej używając tablicy roboczej, która jest specjalną forma concurrency::array, która zapewnia podpowiedź dla środowiska uruchomieniowego AMP odnośnie do czasu optymalizacji tablicy dla częstych transferów między tablicą, a innymi tablicami w określonym akceleratorze.

// 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;
});

Zobacz też

Inne zasoby

Utwórz pierwsze aplikacje Windows Store przy użyciu języka C++

Tworzenie składników środowiska wykonawczego systemu Windows języku C++