Fundamentos de C++ AMP - Parte 1 - O que é? Para que serve? Hello World

Por 1 julho, 2013Sem categoria

Tempo de leitura: 1 minuto

Olá. Tudo certo?

Depois de um tempo com pouca atividade, resolvi resgatar posts mais técnicos aqui para o blog. Com base nisso, resolvi iniciar uma nova série falando sobre uma tecnologia que me fascina um bocado: C++ AMP

O que é C++ AMP?

De forma simplificada, podemos dizer que C++ AMP é a combinação de uma extensão para a linguagem C++ e de uma pequena biblioteca, criada pela Microsoft, que facilita o desenvolvimento de aplicações que tirem proveito da capacidade de execução paralela das GPUs (processadores disponíveis em placas gráficas).

Para que serve C++ AMP?

Comecemos com a explicação disponível no site do MSDN:

C++ AMP (C++ Accelerated Massive Parallelism) accelerates the execution of your C++ code by taking advantage of the data-parallel hardware that's commonly present as a graphics processing unit (GPU) on a discrete graphics card. The C++ AMP programming model includes support for multidimensional arrays, indexing, memory transfer, and tiling. It also includes a mathematical function library. You can use C++ AMP language extensions to control how data is moved from the CPU to the GPU and back.

Ou seja, C++ AMP faz "a ponte" entre o código que a CPU executa, bem como seus dados, e o código em execução na GPU com seus dados.

C++ AMP é suportado por ferramentas que conhecemos

C++ AMP é amplamente suportada pelo Visual Studio. Além disso, programas escritos utilizando essa tecnologia são plenamente compatíveis com máquinas usando Windows.

Para utilizar C++ AMP não é necessário aprender uma nova ferramenta, ou uma nova linguagem.

C++ AMP facilita compatibilidade

Uma vez que o código tenha compilado, o mesmo executável será capaz de executar em uma ampla diversidade de máquinas desde que estas tenham suporte para DirectX 11. Não há restrição para uma determinada marca de placa de vídeo.

A distribuição consiste em copiar o executável com algumas DLLs.

Programas escritos com C++ AMP também é compatível com o conceito de computação em nuvem.

Hello C++ AMP World

Stop to talk, show me the code!

Para explicar os fundamentos de C++ AMP, ouso começar com uma variação de um exemplo recorrente para a tecnologia.

Comecemos com uma versão que não utiliza C++ AMP:

#include

int main()
{
using namespace std;

int a_data[] = {1, 2, 3, 4, 5};
int b_data[] = {6, 7, 8, 9,10};
int sum_data[5];

for (int i = 0; i < 5; i++) sum_data[i] = a_data[i] + b_data[i]; for (int i = 0; i < 5; i++) cout << sum_data[i] << "... "; return 0; } [/code] ... agora, vejamos uma que  utiliza: [code language="cpp"] #include
#include

int main()
{
using namespace std;
using namespace concurrency;

int a_data[] = {1, 2, 3, 4, 5};
int b_data[] = {6, 7, 8, 9,10};
int sum_data[5];

array_view a(5, a_data);
array_view b(5, b_data);
array_view sum(5, sum_data);
sum.discard_data();

parallel_for_each(sum.extent, [=] (index<1> i) restrict(amp) {
sum[i] = a[i] + b[i];
});

for (int i = 0; i < 5; i++) cout << sum[i] << "... "; return 0; } [/code] O programa em sí não apresenta nada de interessante. Basicamente, somamos elementos de dois vetores colocando os resultados em um terceiro. Entretanto, a forma como isso é feito varia um bocado. O primeiro programa utiliza apenas os recursos da CPU. Enquanto isso, o segundo, utiliza a GPU para completar o trabalho. Importante destacar que esse programa é uma variação do exemplo no site do MSDN. Há uma boa explanação sobre cada elemento por lá - recomendo muito a leitura.

Aqui, gostaria de relacionar apenas alguns aspectos chave. Vejamos:

  • C++ AMP cria um "visão" em torno dos dados que serão utilizados pela placa gráfica. Na prática, em tempo de execução, haverá um transporte de dados da memória convencional para a memória da placa de vídeo onde o processamento ocorrerá. No final, os dados da placa de vídeo são retornados para a memória convencional;
  • A função discard_data orienta o run-time de que os valores de uma determinada fonte não são entradas relevantes para o processamento e, por isso, não precisam ser copiados;
  • O modificador const int serve para indicar que os dados representados serão utilizados apenas como "entrada" e que não há necessidade de retornar dados da memória da placa de vídeo quando o processamento for encerrado;
  • A função parallel_for_each é parte da biblioteca do C++ AMP. Ela "operacionaliza" o transporte dos dados e a execução do programa na placa de vídeo;
  • O modificador restricted(amp) indica para o compilador que o código do bloco que segue deverá ser compatível com execução na GPU;
  • Em tempo de execução, o código "marcado" com restricted(amp) é convertido para algo que pode ser executado na GPU (se isso for possível).

O que aprendemos?

Para concluir, um pequeno review:

  • C++ AMP é uma tecnologia poderosa que permite que escrevamos aplicações que tirem proveito da capacidade de execução paralela das GPUs utilizando C++.
  • A curva de aprendizado para C++ AMP é pequena. Afinal, há apenas uma pequena biblioteca e poucas extensões a linguagem C++ que já conhecemos.
  • Código escrito com C++ AMP é potencialmente mais compatível do que aqueles escritos em tecnologias com propósito similar.

Próximos passos

Antes de avançar para o próximo post, recomendo a leitura desses artigos.

Era isso.

Deixe aqui seu comentário... Sem Comentários

Deixe uma Resposta