Condividi tramite


Utilizzo di C++ AMP nelle applicazioni Windows Store

È possibile utilizzare AMP C++ (C++ Accelerated Massive Parallelism) nell'applicazione Windows Store per eseguire calcoli su GPU (unità di elaborazione grafica) o altri acceleratori computazionali.Tuttavia, AMP C++ non fornisce le API per utilizzare direttamente i tipi di Windows Runtime (WinRT) e WinRT non fornisce un wrapper per AMP C++.Quando si utilizzano i tipi di WinRT nel codice—inclusi quello che si sono creati—è necessario convertirli in tipi compatibili con AMP C++.

Considerazioni sulle prestazioni

Se si utilizza Estensioni componenti Visual C++ (C++/CX) per creare un'applicazione Windows Store, si consiglia di utilizzare i tipi plain-old-data (POD) insieme con l'archiviazione contigua—ad esempio, std::vector o array in stile C—per i dati che verranno utilizzati del AMP C++.Questa funzionalità consente di ottenere alte prestazione utilizzando i tipi non-POD, o i contenitori di Windows RT perché non deve avvenire nessun marshaling.

Nel kernel di AMP C++, per accedere ai dati che vengono memorizzati in questa modalità, è sufficiente eseguire il wrapping di std::vector o una matrice di memoria in un concurrency::array_view quindi utilizzare questo array view in un ciclo 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];
});

Marshaling dei tipi di Windows Runtime

Quando si utilizzano le API WinRT, è possibile utilizzare C++ AMP sui dati archiviati in un contenitore WinRT come un Platform::Array<T>^ o nei tipi di dati complessi come classi o strutture che vengono dichiarate utilizzando la parola chiave ref o la parola chiave value.In queste situazioni, è necessario eseguire un lavoro aggiuntivo per rendere disponibili i dati di AMP C++.

JJ856977.collapse_all(it-it,VS.110).gifPiattaforma::Array<T>^, dove T è un tipo POD

Quando si incontra Platform::Array<T>^ e T è un tipo POD, è possibile accedere alla archiviazione relativa sottostante , semplicemente utilizzando il get :

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

Se T non è un tipo POD, utilizzare la tecnica descritta nella seguente sezione, per utilizzare i dati con il C++ AMP..

JJ856977.collapse_all(it-it,VS.110).gifTipi di Windows Runtime: classi di riferimento e classi di valore

C++ AMP non supporta i tipi di dati complessi.Questo include i tipi di non-POD e qualsiasi tipo che viene dichiarato utilizzando la parola chiave ref o la parola chiave value.Se un tipo non supportato viene utilizzato in un contesto restrict(amp), verrà generato un errore in fase di compilazione.

Quando si incontra un tipo non supportato, è possibile copiare parti interessanti dei dati in un oggetto di concurrency::array.Inoltre per rendere i dati disponibili per essere utilizzati con C++ AMP, questo approccio manuale può inoltre migliorare le prestazione massimizzando la località dei dati, assicurando che i dati che non verranno utilizzati per essere copiati nell'acceleratore.È possibile migliorare ulteriormente le prestazioni utilizzando una matrice di gestione temporanea, un form speciale di concurrency::array che fornisce un suggerimento al runtime AMP, la matrice deve essere ottimizzata per un trasferimento frequente tra essa ad altre matrici specifiche dell'acceleratore.

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

Vedere anche

Altre risorse

Creare la prima applicazione Windows Store utilizzando C++

Creare componenti per il Windows Runtime in C++