Comparando CPU vs GPU usando OpenCL

CPU GPU OpenCL

Atualmente temos uma demanda muito grande por mais poder de processamento e velocidade em dispositivos tecnológicos. Para acompanhar o ritmo desses avanços, empresas encontram diversos meios para melhorar poder de processamento em dispositivos. Um meio que a Apple Inc. encontrou foi criar a Open Computing Language (OpenCL). No dia 16 de Junho de 2008 a Apple propôs para o Khronos Group para trabalharem no OpenCL. Depois de 5 meses tomando muito café e programando, no dia 8 de Dezembro de 2008, OpenCL 1.0 foi divulgado para a comunidade.

OpenCL é uma API de baixo nível para programação paralela de diversos tipos de processadores que podem ser encontrados em computadores pessoais, servidores, dispositivos mobile, como também em sistemas embarcados. A linguagem de programação usada pelo OpenCL é uma linguagem parecida com C e pode ser usada em plataformas heterogêneas que contêm CPUs, GPUs, e processadores de fabricantes como NXP, Nvidia, Intel, AMD e IBM. O propósito do OpenCL é acelerar e melhorar a capacidade de resposta das mais diversas aplicações encontradas no mercado, desde jogos e entretenimento até aplicações médicas e científicas.

Neste artigo iremos experimentar o OpenCL usando o SOM Apalis iMX6Q da Toradex, comparando duas aplicações. Uma delas irá rodar na GPU do processador e a outra na própria CPU. No final compartilharemos os resultados obtidos.

Hardware Usado

O computador em módulo da Toradex Apalis iMX6Q é baseado no processador iMX6Quad da NXP, o qual oferece recursos de processamento eficientes particularmente adequados a aplicações gráficas e multimídia. O processador tem quatro núcleos ARM® Cortex-A9® com até 800MHz por núcleo. Além do processador, o computador em módulo conta com memórias de 2GB DDR3 RAM (64bit) e 4GB eMMC Flash.

Focando em propósitos gráficos e de multimídia, o processador também oferece uma GPU 3D Vivante GC2000 que é capaz de suportar OpenCL EP (Embedded Profile) versão 1.1, portanto, podemos usar o poder de processamento da GPU do Apalis iMX6Q em diversas aplicações.

Suporte à  OpenCL na imagem de Linux embarcado da Toradex 

Partimos do ponto onde já possuímos um ambiente de geração de imagens OpenEmbedded já configurado e pronto para gerar uma imagem para Apalis iMX6Q. Isso pode ser realizado seguindo o artigo no Portal de Desenvolvedores da Toradex.

Para gerar uma imagem de Linux embarcado que suporta OpenCL EP 1.1 e também inclui suas bibliotecas, é necessário realizar alguns passos adicionais descritos adiante.

Primeiro, edite o arquivo do seguinte diretório:

Adicionando o seguinte conteúdo:

Também adicione o pacote imx-gpu-viv no arquivo local.conf:

E inicie o processo de geração de uma imagem Desktop:

Código da GPU e CPU

Todo o código neste artigo pode ser encontrado no GitHub

Como exemplo, usamos duas aplicações que basicamente somam vetores. O primeiro código é executado na GPU e o segundo na CPU. O tempo consumido é mostrado no terminal quando as aplicações se encerram. O header necessário para usar OpenCL é cl.h e pode ser encontrado em /usr/include/CL no rootfs. As bibliotecas necessárias para rodar os programas são libGAL.so, que faz as chamadas para a GPU Vivante GC2000, e libOpenCL.so, que corresponde às implementações e interfaces do OpenCL. Ambas podem ser encontradas em /usr/lib

Para o cálculo do tempo consumido, criamos uma queue, com profilling habilitado, e então lemos as informações de profilling no final do programa.

Segue o código do OpenCL:

O código da CPU por sua vez é um código escrito puramente em C que realiza a mesma soma de vetores do programa anterior. Para calcular o tempo consumido usamos a biblioteca time.h. O código é visto a seguir:

Cross Compilando as Aplicações

Um mesmo Makefile pode ser usado para realizar compilacão-cruzada de ambas as aplicações: CPU e GPU. Atente para as três variáveis seguintes do Makefile que precisam ser editadas de acordo com seu sistema:

  • ROOTFS_DIR - Diretório do sysroots do Apalis iMX6;
  • APPNAME - Nome da aplicação;
  • TOOLCHAIN - Diretório da toolchain para cross-compilar.

Salve o Makefile no mesmo diretório da aplicação e execute make. Copie os binários para o módulo Apalis iMX6 da forma que julgar apropriado (SCP, FTP, etc).

Resultados Finais

Depois de executar ambas as aplicações obtivemos os seguintes resultados:

Baseando-se nos resultados podemos ver claramente que conseguimos acelerar o cálculo de soma de vetores usando o poder de processamento da GPU do módulo Apalis iMX6Q por quase 65 vezes (64.92, para ser mais exato)!

Conclusão

Aqueles que desejam aproveitar-se da GPU Vivante GC2000 presente no Apalis iMX6 podem, além de outros métodos, usar OpenCL para aumentar o poder de processamento em rotinas que exigem muitos cálculos vetoriais e matriciais. Com os recursos do OpenCL é possível rodar aplicações em dispositivos desde placas de vídeo e supercomputadores até sistemas embarcados como visto neste artigo. Poderiam até mesmo ir além, por exemplo, utilizando OpenCL com OpenCV para aumentar a performance de aplicações de visão computacional. Este artigo serve de exemplo para infindas possibilidades de aplicações que uma empresa pode desenvolver.

Referências

https://www.khronos.org/opencl/
https://en.wikipedia.org/wiki/OpenCL
http://www.drdobbs.com/parallel/a-gentle-introduction-to-opencl/231002854
https://community.freescale.com/docs/DOC-93984
https://community.freescale.com/docs/DOC-100694
http://developer.toradex.com/products/apalis-imx6
https://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clGetEventProfilingInfo.html
http://parallelis.com/how-to-measure-opencl-kernel-execution-time/
https://software.intel.com/en-us/articles/intel-sdk-for-opencl-applications-performance-debugging-intro
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Linux Embarcado » Comparando CPU vs GPU usando OpenCL
Comentários:
Notificações
Notificar
guest
2 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Vinicius De Araujo Barboza
Vinicius de Araujo Barboza
29/07/2016 11:09

Giovanni! Usei esse mesmo teste como comparativo entre CPU e GPU de um Samsung ARM Chromebook alterando algumas coisas no Makefile e obtive valores consistentes com os seus. Achei que seria interessante podermos comparar o HostOutputVector do código executado na CPU e GPU, mas quando tento o print desse vetor no código da GPU tenho apenas zeros (0 0 0 .. 0 0 0) - já o código da CPU está legal. Consegue me ajudar? Talvez eu tenha esquecido algo na hora de carregar o buffer da GPU no host, afinal só adicionei umas 2 linhas para um for-loop e… Leia mais »

Giovanni Bauermeister
Giovanni Bauermeister
Reply to  Vinicius de Araujo Barboza
01/08/2016 17:40

Olá Vinicius!

Que bom que conseguiu executar o artigo e chegar nos resultados!

Para escrever o código do OpenCL tomei como base o seguinte tutorial:
https://community.nxp.com/docs/DOC-93984

Originalmente o código "printava" os vetores mas não mostrava o tempo das operações. Eu tirei essa parte do código e modifiquei também pra fazer o cálculo do tempo.

Mas se você olhar no original logo após
clReleaseMemObject(GPUOutputVector);

tem o for com o printf

clReleaseMemObject(GPUOutputVector);
for( int i =0 ; i < SIZE; i++)
printf("[%d + %d = %d]n",HostVector1[i], HostVector2[i], HostOutputVector[i]);
return 0;

talvez isso te ajude

Talvez você goste:

Séries

Menu

WEBINAR
 
Debugging
em Linux embarcado

 

Data: 30/09 às 19:30h - Apoio: Mouser Elecctronics
 
INSCREVA-SE AGORA »



 
close-link