Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Você pode usar C++ AMP (C++ Accelerated Massive Parallelism) em seu aplicativo da Plataforma Universal do Windows (UWP) para executar cálculos na GPU (Unidade de Processamento Gráfico) ou em outros aceleradores computacionais. No entanto, o C++ AMP não oferece APIs para manipular diretamente tipos de Tempo de Execução Windows, e o Tempo de Execução Windows não fornece um invólucro para C++ AMP. Ao usar tipos do Tempo de Execução do Windows em seu código, incluindo aqueles que você mesmo criou, você deve convertê-los em tipos compatíveis com C++ AMP.
Observação
Os cabeçalhos AMP C++ foram preteridos a partir do Visual Studio 2022 versão 17.0.
A inclusão de cabeçalhos AMP gerará erros de compilação. Defina _SILENCE_AMP_DEPRECATION_WARNINGS antes de incluir quaisquer cabeçalhos AMP para silenciar os avisos.
Considerações sobre desempenho
Se você estiver usando extensões de componente do Visual C++ C++/CX para criar seu aplicativo da Plataforma Universal do Windows (UWP), recomendamos que você use tipos de dados antigos (POD) com armazenamento contíguo, por exemplo, std::vector ou matrizes no estilo C, para dados que serão usados com AMP C++. Isso pode ajudá-lo a obter um desempenho maior do que usando tipos não-POD ou contêineres do Tempo de Execução do Windows, pois nenhum marshaling precisa ocorrer.
Em um kernel AMP C++, para aceder aos dados armazenados dessa maneira, basta envolver o armazenamento de array de std::vector em um concurrency::array_view e depois usar a visualização de array num loop 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 tipos do Tempo de Execução do Windows
Ao trabalhar com APIs do Tempo de Execução do Windows, convém usar o C++ AMP em dados armazenados em um contêiner do Tempo de Execução do Windows, como um Platform::Array<T>^ ou em tipos de dados complexos, como classes ou structs, declarados usando a palavra-chave ref ou a palavra-chave value . Nessas situações, você tem que fazer algum trabalho extra para tornar os dados disponíveis para C++ AMP.
Plataforma::Array<T>^, onde T é um tipo de POD
Quando encontrares um Platform::Array<T>^ e T for um tipo POD, podes aceder à sua memória subjacente apenas usando a função membro get:
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));
Se T não for um tipo POD, use a técnica descrita na seção a seguir para usar os dados com C++ AMP.
Tipos do Tempo de Execução do Windows: classes de referência e classes de valor
O C++ AMP não suporta tipos de dados complexos. Isso inclui tipos não-POD e quaisquer tipos que são declarados usando a palavra-chave ref ou a palavra-chave value . Se um tipo sem suporte for usado em um restrict(amp) contexto, um erro em tempo de compilação será gerado.
Quando encontrar um tipo sem suporte, pode copiar partes interessantes dos seus dados para um objeto concurrency::array. Além de disponibilizar os dados para o C++ AMP consumir, essa abordagem de cópia manual também pode melhorar o desempenho maximizando a localidade dos dados e garantindo que os dados que não serão usados não sejam copiados para o acelerador. Você pode melhorar ainda mais o desempenho usando uma matriz de preparo, que é uma forma especial que fornece uma dica para o tempo de execução do concurrency::array AMP de que a matriz deve ser otimizada para transferência frequente entre ela e outras matrizes no 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;
});
Ver também
Crie seu primeiro aplicativo UWP usando C++
Criando componentes do Tempo de Execução do Windows em C++