Usar C++ AMP en aplicaciones de la Tienda Windows

Puede utilizar el AMP de C++ (Massive acelerado C++ Paralelismo) en la aplicación de Tienda Windows para realizar cálculos en el GPU (procesamiento de gráficos Unit) u otros aceleradores de computación.Sin embargo, el AMP de C++ no proporciona las API para trabajar directamente con los tipos de (WinRT) en tiempo de ejecución de Windows, y WinRT no proporciona un contenedor para el AMP de C++.Cuando utiliza los tipos de WinRT en código- incluidos los que ha creado se mismo- debe convertirlos a tipos que son compatibles con el AMP de C++.

Consideraciones de rendimiento

Si usa Extensiones de componentes de Visual C++ (C++/CX) para crear la aplicación de Tienda Windows, se recomienda utilizar los tipos de (POD) de los llano-viejo- datos así como contiguo almacenamiento- para el ejemplo, std::vector o el estilo de C matriz- para los datos que se usará con el AMP de C++.Esto puede ayudarle a lograr un rendimiento más alto que mediante tipos o contenedores no - POD de Windows RT porque ningún cálculo debe aparecer.

En el AMP kernel de c++., tener acceso a los datos que se almacena de esta manera, simplemente ajuste std::vector o el de matriz en concurrency::array_view y utilice la vista de matriz en un bucle de 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];
});

Tipos en tiempo de ejecución de Windows de cálculo

Al ejecutar WinRT API, puede utilizar el AMP de C++ en los datos almacenados en un contenedor de WinRT como Platform::Array<T>^ o en tipos de datos complejos como clases o structs que se declaran con la palabra clave de ref o la palabra clave de value.En estas situaciones, tiene que hacer algún trabajo adicional para colocar datos a disposición del AMP de C++.

JJ856977.collapse_all(es-es,VS.110).gif^ De Platform::Array<T>, donde es un tipo t de POD

Cuando se encuentra Platform::Array<T>^ y t es un tipo POD, puede tener acceso al almacén subyacente simplemente utilizando la función miembro de 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 no es un tipo POD, use la técnica que se describe en la sección siguiente para utilizar los datos con el AMP de C++.

JJ856977.collapse_all(es-es,VS.110).gifTipos en tiempo de ejecución de Windows: clases de referencia y clases de valor

El AMP de C++ no admite tipos de datos complejos.Esto incluye los tipos no - POD y cualquier tipo que se declaran con la palabra clave de ref o la palabra clave de value.Si se utiliza un tipo no compatible en un contexto de restrict(amp), se genera un error en tiempo de compilación.

Cuando se encuentra un tipo no compatible, puede copiar elementos interesantes de los datos en un objeto de concurrency::array.Además de crear los datos disponibles para que el AMP de C++ utiliza, este enfoque de la manual- copia también puede mejorar el rendimiento maximizando lugar de los datos, y asegurarse de que los datos que no se usará no se está copiando el acelerador.Puede mejorar el rendimiento más utilizando una matriz provisional, que es una forma especial de concurrency::array que proporciona una sugerencia al motor en tiempo de ejecución de AMP que la matriz se debe optimizar para la transferencia frecuente entre él y otras matrices en el acelerador especificado.

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

Vea también

Otros recursos

Cree la primera aplicación de almacén de Windows mediante C++

Crear componentes de tiempo de ejecución de Windows en C++