CILAMCE 2011

Pelo terceiro ano consecutivo, estaremos organizando um simpósio sobre supercomputação com placas gráficas no CILAMCE.

O CILAMCE é o Congresso Ibero-Latino-Americano de Métodos Computacionais em Engenharia, e em 2011 está na sua 32ª edição. O congresso acontecerá em Ouro Preto – MG, entre 13 e 16 de Novembro deste ano.

A deadline para submissão de resumos é 1º de Maio. Preparem seus trabalhos! Vamos nos encontrar em Ouro Preto para discutir GPGPU!

Para mais detalhes sobre o CILAMCE, visite o site oficial.

CUDA para CPU – MCUDA

Vejam que idéia interessante:

.

CUDA é um modelo de programação de paralelismo de dados que oferece várias abstrações-chave como thread blocks, hierarquia de memória e barreira de sincronização para escrever aplicações. Esse modelo tem sido provado eficiente para a programação de GPUs.

Esse paper de Stratton, Stone & Hwu (2008) descreve um framework chamado MCUDA, que permite que programas CUDA sejam executados eficientemente em multi-core CPUs de memória compartilhada.

Com esses resultados, eles mostram que CUDA pode ser um model de programação paralela eficiente não só para arquiteturas de GPUs.

.

Clique aqui para ver o artigo.

Clique aqui para ver a página de download do MCUDA.

Instalação do CUDA 3.0 no Ubuntu 10.04

Roteiro para instalação do CUDA no Ubuntu 10.04 de 32 ou 64 bits.

por L. G. Turatti

1. Baixar o driver de video 195.36.24 para 32 ou 64 bits;

2. Remover os drivers nvidia instalados

sudo apt-get –purge remove nvidia-*

Saiba mais

Mini-simpósio no MECOM-CILAMCE 2010

Introdução do nosso mini-simpósio no MECOM-CILAMCE 2010 -IX Congresso Argentino de Mecânica Computacional e XXXI Congresso Ibero-Latino-Americano de Mecânica Computacional. Esses congressos acontecerão entre 15 e 18 de novembro de 2010 em Buenos Aires. Prepare seu trabalho!

Title

High Performance Computing on Graphics Hardware (GPGPU)

Organizers

Euclides Mesquita, euclides@fem.unicamp.br
Josué Labaki, labaki@fem.unicamp.br
Luiz Otávio Saraiva Ferreira lotavio@fem.unicamp.br

Department of Computational Mechanics DMC
School of Mechanical Engineering -FEM
State University at Campinas – UNICAMP/Brazil.

Summary

After a long period of steady growth, desktop commodity computer architecture has reached its ceiling on computing performance. Further progress is no longer enabled by growth in core clock rates, but by growth in parallelism. Many articles have been presented in the last editions of CILAMCE and MECOM on the use of multi-cored computing applied to a variety of problems. Furthermore, there is a growing trend toward parallel computation on the recently created general-purpose graphics hardware (GPGPU) [1]. Due to its architecture, the GPU is specially well-suited to address problems that can be expressed as data-parallel computations with high arithmetic intensity (the ratio of arithmetic operations to memory operations) [2]. Recent works have been shown astonishingly fast computations. For instance, papers on the use of GPGPU for computational mechanics have been reporting performances up to 100 times faster than CPUs for solution of linear systems, and around 900 times faster for numerical solution of infinite oscillatory integrals [3]. The first edition of this mini-symposium on CILAMCE 2009 has shown that the GPU has been investigated by researches of a very broad range of subjects in computational modeling with considerable gains in performance. The idea of the present mini-symposium is to gather researchers working on HPC tasks using GPGPU systems, aiming to discuss the state of the art issues, exchange experiences and solutions for existing implementation strategies and problems.

Suggested readings

[1] OWENS, J. D. et al., “A Survey of General-Purpose Computation on Graphics Hardware”, Computer Graphics, 26, 1 (2007), pp.  80-113.

[2] NVIDIA. “NVIDIA CUDA – Compute Unified Device Architecture – Programming Guide”. NVIDIA Corporation, Santa Clara (2008).

[3] MESQUITA, E.; LABAKI, J.; FERREIRA, L. O. S. “An Implementation of the Longman’s Integration Method on Graphics Hardware”. Computer Modeling in Engineering and Sciences, 51, 2 (2009), pp. 143-168.

Comparação GPU x sistemas paralelos

Monografia de conclusão de curso de A. V. Grammelsbacher e J. C. C. Medrado.

O trabalho visa fornecer um estudo comparando a execução de algoritmos paralelos na CPU e na GPU, elucidando se é mais vantajoso executar determinados algoritmos na CPU ou na GPU. Para realizar as comparações são feitos benchmarks da execução de algoritmos com a finalidade de medir a capacidade de processamento em FLOPS , a cópia de dados na memória entre outras características do sistema.

Comparacao de desempenho entre GPGPU e Sistemas Paralelos

CILAMCE 2009

Organizamos um mini-simpósio sobre supercomputação com GPU no 30º Congresso Ibero-Latino-Americano de Métodos Computacionais em Engenharia – CILAMCE 2009. O objetivo era reunir as pessoas que estão trabalhando com esse assunto no Brasil.

O resultado foi melhor do que esperávamos. Treze resumos foram submetidos, e seis trabalhos foram apresentados. Veja os trabalhos apresentados:

[1] K. Raizer, H. S. Idagawa, E. G. O. Nóbrega, L. O. S. Ferreira:

Training and Applying a Feedforward Multilayer Neural Network in GPU [ver].

[2] H. F. Gasparoto, L. O. S. Ferreira:

Development of a Heuristic Type “Generate And Test”, Parallel and Random, to Optimize Functions in GPU [ver].

[3] L. Y. Pozzo, H. S. Idagawa, L. O. S. Ferreira:

Solver Development for Linear Systems by Steepest Descent Method for Parallel Processing on GPU [ver].

[4] J. Labaki, L. O. S. Ferreira, E. Mesquita:

Implementation of Quadratic Boundary Elements for 2D Potential Problems on Graphics Hardware – GPU [ver].

[5] G. B. Vitor, J. V. Ferreira, A. Körbes:

Fast Image Segmentation by Watershed Transform on Graphical Hardware [ver].

[6] T. M. Buriol, M. A. Argenta:

Acelerando o Desenvolvimento e o Processamento de Análises Numéricas Computacionais Utilizando Python e Cuda [ver].

.

Nos vemos no CILAMCE 2010 – Buenos Aires!

Vídeo: tecnologia GPU

Ótimo vídeo mostrando as principais ferramentas da tecnologia GPGPU. Trata-se da palestra de abertura da GPU Technology Conference, que aconteceu em San Jose de 30 de setembro a 2 de outubro deste ano.

Download: http://www.nvidia.com/content/GTC/videos/GTC09-1412.flv

Palestrante: Will Ramey, gerente de produto da NVidia.

Conteúdo postado por Luís Ramirez na lista GPUBrasil.

Sinopse do artigo: BEMxGPU

Achei um artigo muito interessante,

Takahashi, T.; Hamada, T. (2009): “GPU-accelerated boundary element method for Helmhotz’ equation in three dimensions“.

Mesmo para quem conhece Elementos de Contorno, vale a pena ler o artigo. Aprendi várias coisas sobre GPU com ele, mesmo sem ter entendido muito a parte de Elementos de Contorno (apesar de ser minha área de pesquisa):

Peak performance

O artigo fala que “um processador escalar é capaz de executar 2 operações aritméticas por ciclo de clock. Nossa GPU tem 1.17 GHz e 12 multiprocessadores, num total de 96 processadores escalares. Portanto, a peak performance é de 228.1 Gflop/s”.

O “portanto é novo pra mim. Eu não sabia que era possível calcular a peak performance da máquina a partir desses dados… Como dá pra ver o clock da minha GPU no manual (1,296 GHz), e eu sei que ela tem 30 multiprocessadores, agora sei que a peak performance dela é 622.1 Gflop/s.

Fonte de citação

O artigo revê vários conceitos da programação CUDA e da tecnologia GPGPU. Isso é bom não só pra reforçar nosso know-how, mas também é sempre bom ter fontes adicionais pra citar nos nossos artigos. Frases de efeito que o artigo usa que talvez você queira citar:

  • Um warp tem mesmo 32, e não 16 threads;
  • O manual CUDA recomenda blocos com múltiplos de 64 threads para máxima performance;
  • A velocidade de floating-point operations throughput atual das GPUs é até 20 vezes maior que da CPU;
  • Programas de engenharia têm sido experimentados na GPU antes de CUDA, com OpenGL, DirectX, Cg e dispositivos dedicados.

Custo computacional

O artigo revisa o custo computacional de importantes métodos matemáticos. Por exemplo, ele fala que o custo computacional da solução direta de sistemas lineares (como escalonamentos, pivoteamentos, eliminação de Gauss) é da ordem de O(N3), e o consumo de memória é O(N2). Ele diz isso pra justificar a escolha de métodos iterativos no trabalho, como o gradiente conjugado, cujo custo computacional cai pra O(N2) e o consumo de memória cai pra O(N). Boa justificativa pro pessoal que mexe com gradiente conjugado & cia! O artigo ressalva, contudo, que o custo nesses métodos iterativos é proporcional ao número de iterações necessários para o método convergir, e que portanto um pré-condicionamento da matriz é sempre necessário para minimizar esse custo.

Em outro ponto no final do artigo, eles confirmam essa afirmação comparando um pré-condicionador (point-Jacobi), que permitiu convergência em 543 passos e 7498 s, com outro (block-diagonal) que convergiu em 446 passos em 9095 s (não, o resultado não está invertido). Essa diferença de 21% na eficiência justifica investir no estudo de pré-condicionadores.

E já que estamos falando de sistemas lineares: o artigo também alerta que sistemas lineares podem apresentar autovalores fictícios, que podem não só desacelerar a convergência do solver como degenerar os resultados. Há métodos para remover esses autovalores, como o de Burton-Miller, citado no trabalho.

Benchmark justo

Quando comparamos um código em GPU com CPU, os códigos têm que ser o mais parecidos possível para que a comparação seja justa. Para garantir que a comparação seja justa, o artigo faz uma coisa que eu nunca tinha visto: ele conta o número de operações que o algoritmo executa: quantas adições/subtrações, multiplicações, e uso de funções transcendentais. Aí é só garantir que CPU e GPU executem o mesmo número de operações, e a comparação terá sido justa. De quebra, aprendi que há uma forma de executar divisões implementada em hardware! É a função __fdividef(alfa,beta), que equivale a alfa/beta (eu só conhecia __sinf e __cosf).

Precisão mista

O artigo traz uma explicação bem detalhada sobre como fazer precisão mista, que serve para usar precisão dupla só quando for necessário ou para emular precisão dupla em GPUs que não têm esse recurso. Tem até um trecho de código explicando como fazer isso:

static __device__ __inline__ void dsacc0(float *ah, float *al, float b)

{

float t1 = *ah + b;

float e = t1 – *ah;

float t2 = ((b-e) + (*ah – (t1 – e))) + *al;

*ah = t1 + t2;

*al = t2 – (*ah – t1);

}

Todos sabemos que precisão dupla ainda é um ponto fraco das GPGPUs. A maioria só tem precisão simples, e nas que têm precisão dupla, o desempenho é dezenas de vezes inferior do que o da precisão simples. No entanto, precisão dupla, que é inútil em cálculos gráficos, é essencial em problemas de engenharia como o método dos elementos de contorno (assunto do artigo).

Threads por bloco

Na página 18, os autores contam em detalhes como fizeram para otimizar o número de threads por bloco.

  • Nthreads deve ser múltiplo de 64, de acordo com o manual do CUDA;
  • Cada bloco tem somente 16kb de memória compartilhada;
  • Os múltiplos de 64 que não excedem 16kb (neste problema) são: 64, 128, 192, 256 e 320;
  • Blocos com esses números de threads usariam respectivamente 1408, 2816, 4416, 5632 e 7360 registradores (neste problema). Como o número máximo de registradores é 8192, esse não é um parâmetro a se preocupar (neste problema);
  • Dois ou mais blocos são recomendados por multiprocessador, para compensar a carga de latência;
  • Como os blocos de 192, 256 e 320 threads resultariam em menos que isso, essas opções são descartadas;
  • 64 threads resultaria em 5 blocos por multiprocessador, mas o artigo afirma que a eficiência de caching de dados diminui com o tamanho do bloco;
  • Conclusão: o tamanho ótimo do bloco é 128 threads (de largura).

É interessante ler a discussão inteira. Dá várias idéias sobre como escolher o tamanho de bloco nos nossos próprios problemas.

Padrões de floats

Devido à imprecisão dos resultados da GPU, não é uma boa idéia usá-la na integração numérica de singularidades. Como essa integração é necessária no método dos elementos de contorno, os autores fizeram com que a parte singular das integrais fosse calculada pela CPU e a parte não-singular pela GPU. O resultado da integral era a soma dos resultados dos dois dispositivos. Aí a surpresa: GPUs não seguem a mesma especificação IEEE-754 sobre aritmética de ponto flutuante que as CPUs seguem! Assim, a partir de um dado número de elementos, a precisão do resultado da integral “quebrava”, isto é, a integral não melhorava se o integrador fosse refinado.

Observe como a GPU em precisão simples perde precisão mesmo com o aumento do refinamento.

Observe como a GPU em precisão simples perde precisão mesmo com o aumento do refinamento.

Isso parece ter sido tão frustrante que os autores desistiram de usar precisão simples a partir daí (apesar dela ser incrivelmente mais rápida na GPU).

Limite da GPU

Meus programas sempre têm um limite de tamanho de dados que eu posso usar, mas nunca investiguei isso a fundo. No fim, não sei a razão desse limite. Nesse artigo, um gráfico pouco usual é plotado. No eixo y, em vez de milissegundos, são mostrados Gflop/s.

Figura 5: Performance da GPU em tempo total versus tempo de kernel.

Figura 5: Performance da GPU em tempo total versus tempo de kernel.

Como a porcentagem de capacidade de computação do kernel vai sempre se aproximando da do programa completo e o total tende a uma assíntota (claro, a GPU tem uma peak performance), os autores concluíram que o programa deles era limitado pela aritmética, e não pela largura de banda de memória.

Boa leitura!

Curso CUDA

Curso de CUDA no Simulation-Based Engineering Laboratory. Contém os slides e áudio do curso, além de exercícios, projetos da turma, e uma excelente introdução sobre colisão/detecção de corpos.

Sugestão do Luís Ramirez para a lista GPUBrasil.

Medição de tempo

Freqüentemente precisamos medir o tempo de execução de um programa, especialmente quando queremos mostrar que um programa em GPU é mais rápido que um em CPU. A maioria das funções que a linguagem C oferece não servem a esse propósito, já que medem o tempo em segundos, e um programa para GPU raramente completa um segundo de execução. As bibliotecas CUDA oferecem um recurso simples para fazer essa medição, em unidades de milissegundos. Eis um exemplo de código:

# include <stdlib.h>

# include <stdio.h>

# include <cutil.h>

int main()

{

float tempo;

unsigned int timer = 0;

CUT_SAFE_CALL( cutCreateTimer( &timer));

CUT_SAFE_CALL( cutStartTimer( timer));

// Região de execução: aqui vai o trecho de código cujo

// tempo de execução queremos medir.

tempo = CUT_SAFE_CALL( cutGetTimerValue(timer));

printf(“A execução durou %5.3f milissegundos\n”, tempo);

CUT_SAFE_CALL(cutDeleteTimer(timer));

}

Parte ou todo esse roteiro não funcionou pra você? Deixe comentário!

Instalação do emulador CUDA

Roteiro para instalação do CUDA em modo de emulação (para quem não tem uma placa da série 8000 ou superior) no Ubuntu 7.10, 8.04 e 8.10 32/64 bits.
Obs.: Ainda não há suporte do NVIDIA/CUDA para as versões do Ubuntu 8.04 (em fase de desenvolvimento) e 8.10 (inexistente). Portanto, para todas as versões do Ubuntu serão usados os arquivos da última revisão estável, no caso 7.10 (32/64 bits).

1. Baixar os seguintes arquivos do site da NVIDIA e salvá-los na pasta raiz da sua área de usuário:

a) O kit de ferramentas (Toolkit): NVIDIA_CUDA_Toolkit_2.0_Ubuntu7.10_x86.run (ou o mais novo);

b) O kit para desenvolvimento de software (SDK): NVIDIA_CUDA_sdk_2.02.0807.1535_linux.run (ou o mais novo).

2. Instale os pacotes de compilação em linguagem C necessários com o seguinte comando:

sudo apt-get install build-essential libglut3-dev libc6-dev-i386 libstdc++6 -y

3. * SOMENTE PARA UBUNTU 8.10 * – O Ubuntu 8.10 possui como compilador padrão o gcc 4.3, que não é compatível com a versão estável do SDK do CUDA. Portanto, deve-se instalar o gcc 4.1 e configurá-lo como sendo uma alternativa de mecanismo de compilação. Isto é feito através dos comandos:

sudo apt-get install gcc-4.1 g++-4.1 –y

sudo update-alternatives –install /usr/bin/gcc gcc /usr/bin/gcc-4.1 60 –slave /usr/bin/g++ g++ /usr/bin/g++-4.1

4. Para proceder com a instalação do toolkit, altere a propriedade do arquivo .run para que seja interpretado como arquivo executável e invoque sua execução através do shell:

sudo chmod +x NVIDIA_CUDA_Toolkit_2.0_Ubuntu7.10_x86.run

sudo ./NVIDIA_CUDA_Toolkit_2.0_Ubuntu7.10_x86.run auto

5. Rode o editor gedit no modo superusuário para acrescentar as seguintes linhas ao final do arquivo de configuração .bashrc

sudo gedit .bashrc

6. Após o editor abrir o arquivo, mova o cursor até a última linha e digite:

export PATH=$PATH:/usr/local/cuda/lib

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib

7. Salve o arquivo e saia do editor.

8. Feche o terminal digitando exit, para que a alteração tenha efeito.

9. Para instalar o SDK, abra novamente o terminal de texto e digite:

sudo chmod +x NVIDIA_CUDA_sdk_2.02.0807.1535_linux.run

sudo ./NVIDIA_CUDA_sdk_2.02.0807.1535_linux.run

10. Entre na pasta do SDK:

cd NVIDIA_CUDA_SDK

11. Compile o SDK utilizando a diretiva de emulação (emu = 1)

sudo make emu=1

12. Entre na pasta dos programas-exemplo compilados

cd bin/linux/emurelease

13. Veja a lista de programas digitando

ls

14. Execute os programas de sua preferência. Por exemplo:

./clock

ou

./dwtHaar1D

Parte ou todo esse roteiro não funcionou pra você? Deixe comentário!

Instalação do CUDA no Ubuntu

Roteiro para instalação do CUDA no Ubuntu 7.10 e 8.04 de 64 bits.

1. Baixar os seguintes arquivos do site da NVIDIA (http://www.nvidia.com/object/cuda_get.html) e salvá-los na pasta raiz da sua área de usuário (como os arquivos são atualizados constantemente no site, seu nome pode variar com freqüência. Adapte a instalação para os nomes atuais):

a) O driver da GPU: NVIDIA-Linux- x86_64-177.13-pkg2.run;

b) O kit de ferramentas (Toolkit): NVIDIA_CUDA_Toolkit_2.0beta2_Ubuntu7.10_x86.run;

c) O kit para desenvolvimento de software (SDK): NVIDIA_CUDA_sdk_2.0beta2_linux.run.

2. Remover os drives proprietários de placa de vídeo NVIDIA por acaso instalados no Ubuntu.

a) Abra uma janela de console;

b) Execute o comando:

sudo apt-get –purge remove nvidia-glx-new nvidia-settings nvidia-kernel-common

3. Instale os pacotes de compilação em linguagem C necessários com o seguinte comando:

sudo apt-get install build-essential libglut3-dev libc6-dev-i386 -y

4. Feche o terminal:

exit

5. Feche o sistema de janelas pressionando simultanamente as teclas CTRL ALT F1.

6. Digite seu nome de usuário e pressione ENTER.

7. Digite sua senha e pressione ENTER

8. Interrompa a execução do servidor do sistema de janelas X: digite

sudo /etc/init.d/gdm stop

9. Habilite a execução do programa de instalação do driver da placa NVidia: digite

sudo chmod +x NVIDIA-Linux-x86_64-177.13-pkg2.run

10. Extraia os arquivos de instalação do driver: digite

./NVIDIA-Linux-x86_64-177.13-pkg2.run -x

11. Instale o arquivo auxiliar libcuda.so: digite

sudo cp NVIDIA-Linux-x86_64-177.13-pkg2/usr/lib/libcuda.so.177.13 /usr/lib/libcuda.so

12. Instale o driver: digite

sudo sh NVIDIA-Linux-x86_64-177.13-pkg2.run

13. Dê um reboot no computador digitando

sudo reboot

14. Após o reboot, entre na sua área e abra um console de texto para instalar o Toolkit e o SDK

15. Para instalar o toolkit, digite:

sudo chmod +x NVIDIA_CUDA_Toolkit_2.0beta2_Ubuntu7.10_x86.run

sudo ./NVIDIA_CUDA_Toolkit_2.0beta2_Ubuntu7.10_x86.run auto

16. Rode o editor gedit no modo superusuário para acrescentar as seguintes linha ao final do arquivo de configuração .bashrc

sudo gedit .baschrc

Após o editor abrir o arquivo, mova o cursor até a última linha e digite

export PATH=$PATH:/usr/local/cuda/lib

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib

Salve o arquivo e saia do editor.

17. Digite exit e feche o terminal digitando exit, para que a alteração tenha efeito.

18. Para instalar o SDK, abra novamente o terminal de texto e digite

sudo chmod +x NVIDIA_CUDA_sdk_2.0beta2_linux.run

./NVIDIA_CUDA_sdk_2.0beta2_linux.run

19. Entre na pasta do SDK

cd NVIDIA_CUDA_SDK

20. Rode o compilador dos programas-exemplo digitando

make

Comentário da Liliana Pozzo: Se você estiver instalando o CUDA 2.1, ocorrerá um erro neste passo. Algo como:

(/usr/bin/ld: cannot find –lXmu

collect2: ld returned 1 exit status  make: *** [../../bin/linux/release/fluidsGL] Error 1

Neste caso, instale também estas duas bibliotecas:

sudo apt-get install libxmu-dev libxmu6

Tente compilar novamente. Para mais informações sobre esse erro, clique aqui.

21. Entre na pasta dos programas-exemplo compilados

cd bin/linux/release

22. Veja a lista de programas digitando

ls

1. Execute os programas de sua preferência. Por exemplo:

./particles

ou

./fluidsGL

Parte ou todo esse roteiro não funcionou pra você? Deixe comentário!

Curso de GPGPU no ICMC/USP

Por Anderson Marco.

AGM_apresentacao

Cuidados na medição de tempo

Adaptado da mensagem enviada por Daniel Medina à lista GPUBrasil.

Pessoal, já faz algum tempo que estou para reviver este tópico e sempre esqueço. Quero compartilhar com vocês um detalhe que me consumiu alguns dias quebrando a cabeça em cima disso.

Ao implementar em meu programa o algoritmo sugerido pelo Labaki para realizar a análise do tempo de execução, notei que o desempenho da GPU estava muito ruim comparado ao da CPU (com volume pequeno de dados estava até maior). Após procurar muito a causa, descobri que o vilão da história é a API do CUDA. Esta camada de software não é inicializada durante a inicialização do programa principal. Ela só é instanciada no momento da primeira chamada a alguma função da API (no meu caso ocorria quando eu chamava a função cuda_malloc pela primeira vez).

# include <stdlib.h>

# include <stdio.h>

# include <cutil.h>

int main()

{

float tempo;

unsigned int timer = 0;

CUT_SAFE_CALL( cutCreateTimer( &timer));

CUT_SAFE_CALL( cutStartTimer( timer));

// Primeiro comando para a GPU (cudaMalloc, por exemplo).

// …

// Região de execução: aqui vai o trecho de código cujo

// tempo de execução queremos medir.

tempo = CUT_SAFE_CALL( cutGetTimerValue(timer));

printf(“A execução durou %5.3f milissegundos\n”, tempo);

CUT_SAFE_CALL(cutDeleteTimer(timer));

}

Ao receber a primeira instrução, a API se inicializa e isto leva um tempo considerável. Empiricamente levantei que esse tempo é de aproximadamente 40ms em uma GTX  280 e 70ms em uma GT 8800.

Para aplicações que duram dias ou semanas, este tempo não chega a ser um problema, mas para aplicações como a minha, cujo tempo de execução é da ordem de milissegundos, este delay é algo altamente indesejável.

Como solução, eu coloquei uma instrução “dummy” (malloc de 0 bytes) no início do algoritmo só para inicializar a placa, e desconsiderei este tempo do cálculo utilizado para comparação entre CPU e GPU. Por ser um custo de tempo intrínseco e que acontece somente uma vez em toda a execução do software, ele pode ser desconsiderado do benchmark. Veja um exemplo.


# include <stdlib.h>

# include <stdio.h>

# include <cutil.h>

int main()

{

float tempo;

unsigned int timer = 0;

CUT_SAFE_CALL( cutCreateTimer( &timer));

// Um comando dummy, sem efeito no programa, só para

// inicializar a placa. Esse passa a ser então o primeiro

// comando de GPU do programa.

float* dummy;

CUDA_SAFE_CALL( cudaMalloc((void**) &dummy, sizeof(float)));

// Só então o cronômetro é ligado:

CUT_SAFE_CALL( cutStartTimer( timer));

// Região de execução: aqui vai o trecho de código cujo

// tempo de execução queremos medir.

tempo = CUT_SAFE_CALL( cutGetTimerValue(timer));

printf(“A execução durou %5.3f milissegundos\n”, tempo);

CUT_SAFE_CALL(cutDeleteTimer(timer));

}

Parte ou todo esse roteiro não funcionou pra você? Deixe comentário!

Programando CUDA pelo NetBeans

Introdução

A plataforma CUDA (Compute Unified Device Architecture), da NVIDIA, é uma plataforma integrada software-hardware para desenvolvimento de aplicações de computação de uso geral utilizando os processadores gráficos (GPUs) da NVIDIA como co-processadores para processamento paralelo de longas cadeias de dados de elevada intensidade aritmética, casos em que há significativo ganho de desempenho com relação às CPUs. Essa plataforma funciona com todas as GPUs a partir da série G80 (Por exemplo: GeForce 8300, GeForce 8600GT, GeForce 8800GTX, GT260, GT280, GT295, etc. Ver lista completa no site da NVIDIA).

O software CUDA pode ser livremente baixado do site da NVIDIA, disponível para as plataformas Windows, OSX e Linux.

Na plataforma Windows, o software deve ser usado integrado ao MS Visual Studio 2005 (Obs: o MS Visual Studio 2008 não funciona bem com a CUDA). Infelizmente o software não funciona com a versão grátis do MSVS, o Visual Studio Express.

Nos sistemas Linux o software CUDA funciona bem se utilizado com terminais de texto, na linha-de-comando, mas alguns usuários ressentem-se da ausência de um ambiente gráfico de desenvolvimento. Os dois principais ambientes gráficos disponíveis são o ECLIPSE e o NetBeans. Apresentarei a seguir um guia passo-a-passo para a configuração do Netbeans 6.5.1 para o desenvolvimento de aplicações para a plataforma CUDA.

Supondo que o interessado já tem o software CUDA instalado na sua máquina, na distribuição Linux Ubuntu 8.10 (senão, veja como).

Instalação do Netbeans 6.5.1

1. Instalar o JDK (Java Development Kit) versão 6 ou superior (site da Sun Microsystems). No ubuntu basta usar o instalador Synaptic.

2. Instalar o Netbeans 6.5.1.

3. Rodar o Netbeans e configurá-lo como descrito a seguir (texto original).

Fazendo o editor reconhecer a extensão .cu

1. Navegue até

Menu->Ferramentas->Opções

2. Clique no botão “Miscelânea”;

3. Selecione a aba “Arquivos”;

4. Clique no botão “Novo…”;

5. Abrir-se-á uma janela com um campo intitulado “Extensão de arquivo:”;

6. Digite “cu” (sem as aspas) no espaço em branco e clique no botão “OK”;

7. Em seguida escolha a opção “Arquivos C (text/x-c)” (sem as aspas) na lista intitulada “Tipo de arquivo associado (MIME)”;

8. Clique no botão “OK”.

Fazendo o editor utilizar o compilador nvcc

1. Navegue até

Menu->Ferramentas->Opções

2. Clique no botão “C/C++”;

3. Seleciona a aba “Outro”;

4. Clique o botão “Editar” ao lado da lista “Extensões arquivo C:”;

5. Abrir-se-á uma janela intitulada “Lista de extensões”;

6. Digite “cu” (sem as aspas) no campo intitulado “Extensão” e clique no botão “Adicionar”;

7. Em seguida clique no botão “OK”.

8. Navegue até

Menu->Ferramentas->Opções

9. Clique no botão “C/C++”;

10. Selecione a aba “Ferramentas de construção”;

11. Clique no botão “Adicionar” da lista “Grupo de ferramentas”

Abrir-se-á uma janela intitulada “Adicionar nova coleção de ferramentas”

12. Clique no botão “Procurar” e navegue até a pasta onde o nvcc está instalado:

/usr/local/cuda/Bin

13. Selecione “GNU” na lista intitulada “Família do grupo de ferramentas”

14. Digite “nvcc” (sem as aspas) no campo intitulado “Nome do grupo de ferramentas”.

15. Clique no botão “OK”, fechando a janela “Adicionar nova coleção de ferramentas”.

16. Clique no botão “OK”, fechando a janela “Opções”.

Abrindo e configurando um projeto CUDA

1. Navegue até

Menu->Arquivo->Novo projeto

Abrir-se-á a janela intitulada “Novo Projeto”;

2. Selecione a opção “C/C++” da lista “Categorias:” e a opção “Projeto C/C++ a partir de código existente” na lista “Projetos”;

3. Clique o botão “Próximo>”;

4. A janela se alterará, aparecendo o campo intitulado “Ferramenta de construção” com a pergunta “Como você constrói o código?”;

5. Selecione a opção “Usando um makefile existente”;

6. Em seguida dê um clique no botão “Procurar…”;

7. Navegue até a pasta de um projeto do NVIDIA_CUDA_SDK. Por exemplo,

/home/seu-nome/NVIDIA_CUDA_SDK/projects/clock,

selecione o arquivo “Makefile” e clique no botão “Selecionar”, voltando à janela anterior;

8. Clique no botão “Próximo>”;

9. A janela se alterará, aparecendo o campo intitulado “Ações de construção”.

10. No campo “Diretório de trabalho:” deve estar o caminho para o diretório onde está o arquivo “Makefile” do projeto. Pode-se tanto digitar o caminho diretamente no campo apropriado quanto navegar até o diretório dando-se um clique no botão “Procurar…”.

11. No campo “Comando Construir:” deve estar o comando que invoca o compilador. O sistema inclui automaticamente a linha de comando “make -f Makefile“, que compila o programa no modo “release” usando o Makefile do projeto. Caso se deseje utilizar o emulador de GPU deve-se substituir a linha de comando por “make emu=1 -f Makefile“.

12. No campo “Comando Limpar:” deve estar o comando “make -f Makefile clean“.

13. No campo “Resultado da construção:” deve estar o caminho do arquivo executável a ser gerado pelo compilador. Pode-se digitar o caminho ou utilizar o botão “Procurar” para navegar até a pasta do programa-objeto, e então digitar o nome do arquivo executável no campo “File name:”, clicando no botão “Selecionar” em seguida;

14. Clique então no botão “Proximo >”;

15. A janela se alterará, aparecendo o campo intitulado “Arquivos de código-fonte”;

16. Abra a lista intitulada “Tipos de arquivo a ser adicionado ao projeto:” e selecione o penúltimo item, que deve conter uma lista semelhante a:

.cpp .cc .c++ .cxx .C .mm .c .i .m .cu .h .H .hpp .hxx .SUNWCCh .tcc .f .F .f90 .F90 .f95 .F95 .f03 .F03 .for .il .mod

Nota: observe que a extensão “.cu” faz parte da lista;

17. Clique então no botão “Proximo >”;

18. A janela se alterará, aparecendo o campo intitulado “Configuração da assistência a código”;

19. Selecione a opção “Configuração automática”;

20. Clique então no botão “Proximo >”;

21. A janela se alterará, aparecendo o campo intitulado “Nome e local do projeto”.

22. Deixe como estão os campos “Nome do projeto:”, “Localização do projeto:” e “Pasta do projeto:”;

23. Ative a seleção “Definir como projeto principal.”.

24. Clique então no botão “Finalizar”.

Seu projeto aparecerá então como uma árvore de diretórios na janela à esquerda do Netbeans;

25. Clique com o botão direito do mouse no nome do projeto (clock_1) e selecione a opção “Propriedades”, que é a mais de  baixo.

26. Abrir-se-á a janela intitulada “Propriedades do projeto -clock_1″;

27. Clique a opção “Construir” da janela “Categorias”, à esquerda;

28. Agora selecione “nvcc” na lista intitulada “Coleção de ferramentas”, do lado direito;

29. Abra a opção “Construir” da árvore de Categorias, clicando na seta à esquerda da palavra “Construir”;

30. Agora clique na palavra “Make” abaixo da palavra “Construir”, e ao lado direito aparecerão as opções de Diretório de trabalho, Comando construir, Comando limpar, e Resultado da construção, já vistos na configuração inicial do projeto. Você poderá, por exemplo, alterar a linha de comando de Construir para que possa ou gerar o código final, ou usar o emulador, ou usar o debug, etc., como convenha;

31. Clique agora a palavra “Executar” na lista de “Categorias”;

32. No campo “Executar diretório” deverá haver o caminho completo para o arquivo executável a ser gerado pelo Make.

33. No campo “Ambiente” deverão ser incluidas as variáveis PATH e LD_LIBRARY_PATH da seguinte forma:

a. Clique no botão “…” à direita da opção “Ambiente”. Abrir-se-á uma janela intitulada “Default – Ambiente”;

b. Clique uma vez no botão “Adicionar”. Aparecerá uma linha vazia na tabela com as colunas “Nome” e “Valor”;

c. Digite “PATH” (sem aspas) no campo “Nome” e “$PATH:/usr/local/cuda/lib” no campo “Valor”;

d. Clique novamente no botão “Adicionar” para acrescentar nova linha à tabela e preencha-a da seguinte forma:

e. Digite “LD_LIBRARY_PATH” (sem aspas) no campo “Nome” e “$LD_LIBRARY_PATH:/usr/local/cuda/lib” no campo “Valor” e clique no botão “OK”;

34. A opção “Construir primeiro” deve estar selecionada;

35. No campo “Tipo de console”, selecione a opção “Terminal externo”;

36. No campo “Tipo de terminal”, selecione a opção “Gnome Terminal”.

37. Clique no botão “OK”.

38. Pressione a tecla F6 para construir e executar o projeto “clock”;

39. Deve abrir-se uma janela de texto e aparecer as seguintes mensagens:

==============================================

Test PASSED

time = 810000

Press ENTER to exit…

==============================================

40. Ao se pressionar a tecla ENTER deve aparecer a seguinte mensagem:

[Pressione Enter para fechar a janela]

41. Pressione a tecla ENTER novamente e a janela se fechará.

Parabéns!!! Você acaba de configurar seu IDE Netbeans para compilar e executar programas CUDA.

Nota

Ao criar um novo projeto, siga a recomendação da NVIDIA: Copie o conteúdo do diretório “template” que está no diretório “projects” do NVIDIA_CUDA_SDK num novo diretório criado para o novo projeto. Em seguida troque os nomes dos arquivos e edite o conteúdo do “Makefile” para adequá-los ao novo projeto.

O que ainda pode ser feito

Configurar o sistema para gerar automaticamente o Makefile dos novos projetos

Parte ou todo esse roteiro não funcionou pra você? Deixe comentário!

Programando CUDA pelo Anjuta

O ambiente de desenvolvimento ANJUTA é mais poderoso, mais fácil de configurar e utilizar que o Netbeans.

1. Para abrir um projeto pré-existente no NVIDIA_CUDA_SDK, simplesmente abra o projeto como

Menu->Arquivo->Novo->5 Projeto a partir de código existente

Abrir-se-á a janela “Importar Projeto”;

2. Clique no botão “Frente”.

Abrir-se-á a janela “Projeto a importar”;

3. Digite um nome para o projeto no campo correspondente (por exemplo, “Fluidos”);

4. Navegue, através da lista na parte de baixo da mesma janela, até o diretório do projeto que deseja importar. No caso, o projeto:

../NVIDIA_CUDA_SDK/projects/fluidsGL

5. Clique no botão “Frente”

Abrir-se-á a janela “Confirmação”, contendo os dados do projeto;

6. Clique no botão “Aplicar”;

7. Abrir-se-á uma nova janela do Anjuta para o projeto, intitulada FluidsGL – Anjuta;

8. Na árvore de arquivos do lado esquerdo dessa janela estão todos os arquivos do projeto. Clique duas vezes no arquivo fluidsGL.cu para abrí-lo com o editor. Se o texto não estiver realçado, navegue até

Menu->Ver->Editor->Modo de realce

e escolha na lista ou o tipo “cpp”, para que o editor utilize o padrão de realce da linguagem C++ nos arquivos do projeto;

9. Para compilar o projeto, simplesmente abra o menu Compilar e escolha a opção “Compilar projeto”;

10. Para executar o código gerado, abra o menu Run e escolha a opção “Executar o programa”.

Abrir-se-á uma janela intitulada “Parâmetros do programa”;

11. Simplesmente navegue, clicando no botão “Abrir”, até o programa executável gerado pela compilação e selecione o arquivo executável. Por exemplo,

/home/luiz/NVIDIA_CUDA_SDK/bin/linux/release/fluidsGL

12. Deixe em branco o campo “Argumentos:”;

13. Clique no campo “Variáveis de ambiente”.

Abrir-se-á uma lista sob o rótulo “Variáveis de ambiente”;

14. Clique no botão “Novo” para criar uma nova entrada na lista;

15. Sob o rótulo “Nome” digite “PATH” (sem as aspas) e pressione a tecla TAB;

16. Sob o rótulo “Valor” digite “$PATH:/usr/local/cuda/lib” (sem as aspas) e clique com o botão esquerdo do mouse em algum ponto da janela;

17. Clique outra vez no botão “Novo” para criar uma nova entrada na lista;

18. Sob o rótulo “Nome” digite “LD_LIBRARY_PATH” (sem as aspas) e pressione a tecla TAB;

19. Sob o rótulo “Valor” digite “$LD_LIBRARY_PATH:/usr/local/cuda/lib” (sem as aspas) e  clique com o botão esquerdo do mouse em algum ponto da janela;

20. Clique no botão “Aplicar”;

21. Caso o programa não rode e reclame que não achou uma biblioteca, abra novamente a janela das variáveis de ambiente acima:

Menu->Run->Parâmetros do programa

e confira se elas estão presentes e com o valor correto (pode ocorrer que os valores não foram admitidos corretamente);

22. Pressione a tecla F3 para rodar o programa;

Aproveite o Anjuta! É um dos melhores IDEs do mundo Linux.

Parte ou todo esse conteúdo não funcionou pra você? Deixe comentário!

Migrando para WordPress

Aguarde: o GPUBrasil.com em breve se tornará um blog.

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.