Partager via


Utilisation de C++ AMP dans les applications Windows Store

Vous pouvez utiliser C++ ampère (parallélisme massif accéléré par C++) dans votre application d' Windows Store pour effectuer des calculs sur le GPU (graphiques traitement l'unité) ou d'autres accélérateurs de calcul.Toutefois, C++ ampère ne fournit pas d'API pour utiliser directement des types d'exécution de (WinRT) windows, et WinRT ne fournit pas un wrapper pour l'ampère C++.Lorsque vous utilisez WinRT dans le code- votre y compris ceux que vous avez créé vous-même- devez les convertir des types compatibles avec l'ampère C++.

Considérations sur les performances

Si vous utilisez Extensions de composant Visual C++ (C++/CX) pour créer votre application d' Windows Store, nous vous recommandons d'utiliser des types integration (POD) process ordinaire-ancien- données avec contigu mémoire- pour l'exemple, l' std::vector ou de style C matrice- pour les données qui seront utilisées avec l'ampère C++.Cela peut vous aider à accomplir une plus haute performance qu'à l'aide de les types non POD ou des conteneurs des fenêtres droite car aucun marshaling ne doit se produire.

Au noyau c++ ampère, pour accéder aux données stockées de cette façon, tout encapsulez std::vector ou rangez la mémoire dans concurrency::array_view et utilisez ensuite la vue du tableau dans une boucle d' 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];
});

Types au moment de l'exécution de fenêtres de marshaling

Lorsque vous travaillez avec les API de WinRT, vous pouvez utiliser C++ ampère sur les données stockées dans un conteneur de WinRT tel qu' Platform::Array<T>^ ou dans les types de données complexes tels que les classes ou les structures qui sont déclarés avec le mot clé d' ref le mot clé ou d' value .Dans ces situations, vous devez exécuter un travail supplémentaire pour rendre des données disponibles à l'ampère C++.

JJ856977.collapse_all(fr-fr,VS.110).gif^ De Platform::Array<T>, où T est un type POD

Lorsque vous rencontrez Platform::Array<T>^ et T est un type POD, vous pouvez accéder à sa mémoire sous-jacente qu'à l'aide de la fonction membre d' 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));

Si T n'est pas un type POD, utilisez la technique décrite dans la section suivante pour utiliser les données à l'ampère C++.

JJ856977.collapse_all(fr-fr,VS.110).gifTypes au moment de l'exécution de windows : classes de référence et classes de valeur

C++ ampère ne prend pas en charge les types de données complexes.Cela inclut les types non POD et les types qui sont déclarés avec le mot clé d' ref le mot clé ou d' value .Si un type non pris en charge est utilisé dans un contexte d' restrict(amp), une erreur de compilation est générée.

Lorsque vous rencontrez un type non pris en charge, vous pouvez copier des parties intéressantes de ses données dans un objet d' concurrency::array .En plus de rendre des données disponibles pour C++ ampère pour consommer, cette approche de manuel- copie peut également améliorer les performances en agrandissant la localité de données, et en vérifiant ces données qui ne sont pas utilisées ne sont pas copiées à l'accélérateur.Vous pouvez améliorer les performances plus loin à l'aide d'un tableau temporaire, qui est un formulaire spécial d' concurrency::array qui fournit un indicateur au runtime d'ampère que le tableau doit être optimisées pour le transfert fréquent entre lui et d'autres tableaux sur l'accélérateur spécifié.

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

Voir aussi

Autres ressources

Créez votre première application de mémoire windows à l'aide de C++

Créer des composants d'exécution windows en C++