6.3.1 Cálculo de Números Perfeitos
256x256 512x512 1024x1024 2048x2048 GPU 930 420 136 31 CPU 24 20 9 2 Seq 7 6 3 0,5 0 100 200 300 400 500 600 700 800 900 1000 FPS Dimensão da imagem / FPS Conjunto de Mandelbrot 100000 500000 1000000 CUDA 0,2 3,6 14 APAR 0,5 7,7 29 0 5 10 15 20 25 30 35 Tem p o (seg u n d os)
Número máximo calculado / Tempo
Números Perfeitos
6.3.2 Cálculo de Números Primos 6.3.3 Multiplicação de Matrizes 100000 500000 1000000 CUDA 0,4 8,2 32 APAR 0,5 8,2 32 0 5 10 15 20 25 30 35 Tem p o (seg u n d os)
Número máximo calculado / Tempo
Números Primos
640x640 1280x1280 1600x1600 3200x3200 CUDA 0,4 0,7 1 4,7 APAR 0,4 2,2 2,8 26 0 5 10 15 20 25 30 Te m p o (se gu n d o s)Dimensão da Matriz / Tempo
Multiplicação de Matrizes
CONCLUSÃO
O aumento de velocidade dramático do núcleo computacional fornece uma forte motivação para o trabalho contínuo em paralelismo com GPGPU. Evidentemente, a paralelização com GPU tem um efeito dramático sobre o tempo total de execução, reduzindo-o por um fator de mais de 10 vezes que por sua vez comparado a energia dissipada pela GPU em questão que é de no máximo 200W com a energia dissipada pela CPU que chega a 130W, teoricamente ela mostra-se uma melhor relação consumo/desempenho.
O novo CUDA 5 se mostrou muito mais prático e fácil de usar, desde a instalação ao desenvolvimento simplificado, sem contar os diversos exemplos que acompanham o SDK.
Com relação ao CUDA, a APARAPI se mostrou bem promissora, apesar de ser relativamente nova quanto ao CUDA, ela fornece aos desenvolvedores Java a possibilidade de paralelizar tarefas na GPU, oque antes era inviável na linguagem. Comparando-se a performance da APARAPI com CUDA, é possível afirmar que os resultados obtidos foram satisfatórios, pois apesar da performance ter sido um pouco menor, deve-se levar em conta que esta está executando sobre uma JVM que consequentemente gera uma perda de desempenho na aplicação, pois não é uma aplicação nativa rodando diretamente sobre o sistema operacional.
A transição de nível de sistema para plataformas de computação exóticas é sempre uma troca de engenharia. Os benefícios de desempenho de um ambiente como esse devem ser suficientemente altos para compensar o custo de desenvolvimento e manutenção com o novo sistema. A plataforma GPGPU e seu ambiente de programação é suficientemente familiar para um programador e expõe a massiva capacidade paralela de uma forma simples. O aumento de desempenho imediato é evidente a partir dos benchmarks preliminares apresentados neste relatório. Significativas otimizações adicionais podem ser realizados em trabalhos futuros através de mais análise e refinamento desta abordagem GPGPU.
Empresas de hardware estão trabalhando duro para fornecer sistemas sólidos acessíveis baseados em GPU, projetados especificamente para computação de propósito geral, e há uma grande quantidade de software disponível para aproveitar as oportunidades oferecidas por esses dispositivos. GPGPUs fornecerem soluções para desafios do mundo real, a partir de renderização de vídeo e alto
desempenho em jogos de computação matemática e análise numérica (GPGPU COMPUTING..., 2010).
Por fim, ainda foi realizada uma comparação entre as APIs CUDA e APARAPI sobre os resultados obtidos nos testes anteriores. Ambas tem uma relação muito próxima e apesar da APARAPI ser uma biblioteca para aplicativos Java, ela converte o código da GPU para código OpenCL, o que também torna muito flexível e com uma melhor performance, o que levou a obter resultados muito próximos ao CUDA. Portanto, com certeza a APARAPI já é uma boa alternativa aos desenvolvedores Java, podendo facilmente tornar uma simples aplicação altamente escalável.
Em trabalhos futuros uma arquitetura alternativa poderia firmemente unir processos de CPU com processos de GPU para maximizar a utilização do sistema. A implementação do kernel da GPU pode ser mais trabalhado conforme o contexto do problema, esta prática otimizaria ainda mais a performance de GPU.
Recomendável também que em trabalhos futuros seja utilizada uma GPU com maior capacidade computacional e principalmente que seja de uma série destinada ao GPGPU assim como a série TESLA, para que possam serem extraídos mais recursos da arquitetura e da própria GPU.
Outra alternativa para trabalhos futuros é fazer uma analise do real consumo de energia de ambas arquiteturas para calcular melhor o custo benefício. Esta analise demonstraria com precisão os dados do consumo para comprovar, ou não, a melhor eficiência energética das GPUs.
REFERÊNCIAS BIBLIOGRAFICAS
ABOUT GPGPU.org. Disponível Em: <http://gpgpu.org/about>. Acesso em: 09 jul.
2012.
ABOUT the Java Technology. Disponível Em:
<http://docs.oracle.com/javase/tutorial/getStarted/intro/definition.html>. Acesso em: 05 set. 2012.
AMD Accelerated Processing Units. Traduzido por: Google Tradutor. Disponível
em: <http://www.amd.com/us/products/technologies/fusion/Pages/fusion.aspx>. Acesso em: 26 mar. 2012.
AMD apresenta o Fusion na CES de 2011. Disponível em: <http://ontheroad.adrenaline.uol.com.br/tecnologia/noticias/7128/amd-apresenta-o- fusion-na-ces-2011.html>. Acesso em 26 mar. 2012.
ARRUDA, Felipe. A história dos processadores. 2011. Disponível Em: <http://www.tecmundo.com.br/historia/2157-a-historia-dos-processadores.htm>. Acesso em: 15 set. 2011.
CARTEY, Luke. Domain Specic Languages for Massively Parallel Processors
PRS Transfer Report. 2010. Disponível Em:
<http://www.hmmingbird.co.uk/downloads/transferreport.pdf>. Acesso em: 18 ago. 2012.
COMPUTER Science. CSC/ECE 506 Spring 2011/ch2a mc. 2011. Disponível Em: <http://pg-
server.csc.ncsu.edu/mediawiki/index.php/CSC/ECE_506_Spring_2011/ch2a_mc>. Acesso em: 22 jul. 2012.
CLUSTERS e Supercomputação. Disponível em:
<http://www.vivaolinux.com.br/artigo/Clusters-e-Supercomputacao>. Acesso em: 26 mar. 2012.
CUDA PROGRAMAÇÃO Paralela Facilitada. Disponível em: <http://www.NVIDIA.com.br/object/cuda_home_new_br.html>. Acesso em: 29 mar. 2012.
CUDA PROGRAME a sua NVIDIA. Disponível em:
<http://pt.opensuse.org/ARTIGOS:CUDA_Programe_a_sua_NVIDIA>. Acesso em: 15 set. 2011.
CUDA programming model. 2008. Disponível Em:
<http://ixbtlabs.com/articles3/video/cuda-1-p5.html>. Acesso em: 20 set. 2012.
CUDA TOOLKIT 4.0 and Parallel Nsight 2.0. Traduzido por: Google Tradutor.
Disponínel em: <http://developer.NVIDIA.com/content/cuda-toolkit-40-and-parallel- nsight-20-now-production-release>. Acesso em: 15 set. 2011.
DALLY, Bill. “PROJECT DENVER” PROCESSOR TO USHER IN NEW ERA OF
COMPUTING. 2011. Disponível Em: <http://blogs.NVIDIA.com/2011/01/project-
denver-processor-to-usher-in-new-era-of-computing>. Acesso em: 2 out. 2012.
DONGARRA, Jack. O Que As Pessoas Estão Dizendo. Disponível em: <http://www.NVIDIA.com.br/object/cuda_home_new_br.html>. Acesso em: 29 mar. 2012.
EL-REWINI, H.; ABD-EL-BARR, M., Advanced Computer Architecture and
Parallel Processing, 2005.
ENTENDA os supercomputadores, potentes máquinas usadas na pesquisa científica. 2011. Disponível Em: <http://www.geek.com.br/posts/15978-entenda-os-
supercomputadores-potentes-maquinas-usadas-na-pesquisa-cientifica>. Acesso em: 05 jun. 2012.
FERLIN, Edson P. O que é Processamento Paralelo?. 2011. Disponível Em: <http://professorferlin.blogspot.com.br/2011/08/o-que-e-processamento-
paralelo.html>. Acesso em: 25 ago. 2012.
FLYNN, Michael J. Disponível em: <http://arith.stanford.edu/~flynn/>. Acesso em:
25 out. 2011.
FROST, Gary. Aparapi: An Open Source tool for extending the Java promise of
‘Write Once Run Anywhere’ to include the GPU. Portland, 2012. Disponível Em:
<http://www.oscon.com/oscon2012/public/schedule/detail/23434>. Acesso em: 15 jun. 2012.
FUTURE generations of General-Purpose Graphics Processing Units (GPGPUs) look to improve performance per watt. 2011. Disponível Em: <http://defense.ge-
ip.com/news-events/detail/2942>. Acesso em: 25 ago. 2012.
GPGPU. Disponível Em: <http://defense.ge-ip.com/products/family/gpgpu>. Acesso
em: 02 ago. 2012.
GPGPU Computing Horizons: Developing and Deploying for Microsoft
Windows. 2010. Disponível Em:
<http://download.microsoft.com/download/A/6/C/A6C0223B-9460-4346-8DC0-
B6BCFD9269B4/MSFT_GPGPU_whitepaper_FINAL.PDF>. Acesso em: 25 out. 2012.
GPU DO PRINCÍPIO ATÉ A COMPUTAÇÃO DE PROPÓSITO GERAL. 2011.
Disponível Em: <http://cavernadati.wordpress.com/2011/07/05/gpu-do-principio-ate- a-computacao-de-proposito-geral>. Acesso em: 21 out. 2012.
GRAMMELSBACHER, Alessandro V; MEDRADO, Jão C. C. COMPARAÇÃO DE
DESEMPENHO ENTRE GPGPU E SISTEMAS PARALELOS. São Paulo, 2009.
Disponível Em: <http://gpubrasil.files.wordpress.com/2009/12/comparacao-de- desempenho-entre-gpgpu-e-sistemas-paralelos.pdf>. Acesso em: 11 jun. 2012.
HARRIS, Mark. CUDA 5 and Beyond. Disponível Em: <http://developer.download.NVIDIA.com/GTC/PDF/GTC2012/PresentationPDF/S064 1-GTC2012-CUDA-5-Beyond.pdf>. Acesso em: 18 set. 2012.
HOLZ, Lucas. Comparação de desempenho entre CPU e GPU usando CUDA. 2010. Trabalho de Conclusão de Curso apresentado como pré-requisito para conclusão do Curso de Ciência da Computação. Universidade Regional do Noroeste do Estado do Rio Grande do Sul. Ijuí, 2010.
HOUSTON, Mike. General Purpose Computation on Graphics Processors
(GPGPU). Disponível Em:
<http://graphics.stanford.edu/~mhouston/public_talks/R520-mhouston.pdf>. Acesso em: 11 set. 2012.
HUANG, Jen-Hsun. NVIDIA CEO Talks Parallel and Shows Roadmap at GTC
2010. 2010. Disponível Em:
<http://www.brightsideofnews.com/news/2010/9/22/NVIDIA-ceo-talks-parallel-and- shows-roadmap-at-gtc-2010.aspx>. Acesso em: 02 out. 2012.
INTEL apresenta co-processador de 1 teraflops. 2011. Disponível Em:
<http://www.inovacaotecnologica.com.br/noticias/noticia.php?artigo=intel-apresenta- co-processador-1-teraflops&id=010150111118>. Acesso em: 30 ago. 2012.
INÍCIO DA ERA DA APU AMD Fusion. Disponível em: <http://www.guiadopc.com.br/noticias/16741/inicio-da-era-da-apu-amd-fusion.html>. Acesso em: 26 mar. 2012.
JEONG, Min Kyu. CUDA ray-tracer. 2008. Disponível Em: <http://www.cs.utexas.edu/~fussell/courses/cs384g/projects/final/artifacts_f08/mjeon g>. Acesso em: 11 jun. 2012.
KEPLER - THE WORLD'S FASTEST, MOST EFFICIENT HPC ARCHITECTURE.
Disponível Em: <http://www.NVIDIA.com/object/NVIDIA-kepler.html>. Acesso em: 01 ago. 2012.
LEPILOV Sergey; Zabelin Alexey. GPU Architecture and Positioning. 2012. Disponível Em: <http://www.xbitlabs.com/articles/graphics/display/NVIDIA-geforce- gtx-680_2.html#sect0>. Acesso em: 13 jun. 2012.
MAZZON, Tiago. Os Fractais. 2012. Disponível Em:
<http://www.deldebbio.com.br/2012/01/16/os-fractais/>. Acesso em: 28 out. 2012. MONNERAT, Luiz R. R. Petrobras muda tecnologia e monta supercomputador. Portland, 2012. Disponível Em: <http://www.geofisicabrasil.com/noticias/37- empresas/2548-petrobras-muda-tecnologia-e-monta-supercomputador.html>.
Acesso em: 18 ago. 2012.
MORAES, Sérgio Ricardo Dos Santos. COMPUTAÇÃO PARALELA EM CLUSTER
DE GPU APLICADO A PROBLEMA DA ENGENHARIA NUCLEAR. Rio de Janeiro,
<http://www.ien.gov.br/posien/teses/dissertacao_mestrado_ien_2012_01.pdf>. Acesso em: 14 set. 2012.
MORIMOTO, Carlos E. O ABC das placas 3D, parte 1. 2010. Disponível Em: <http://www.hardware.com.br/tutoriais/abc-placas-3d/pagina6.html>. Acesso em: 13 set. 2012.
MORIMOTO, Carlos E. Processador. 2007. Disponível Em: <http://www.hardware.com.br/termos/processador>. Acesso em: 28 set. 2012.
NON-GRAPHIC computing with graphics processors. 2008. Disponível Em:
<http://ixbtlabs.com/articles3/video/cuda-1-p1.html>. Acesso em: 20 set. 2012.
NVIDIA GPUDIRECT. Disponível Em: <http://developer.NVIDIA.com/cuda/NVIDIA-
gpudirect>. Acesso em: 17 ago. 2012.
NVIDIA Kepler GPUs Roadmap: GK107, GK106, GK104, GK110 and GK112.
Disponível Em: <http://www.geeks3d.com/20111126/NVIDIA-kepler-gpus-roadmap- gk107-gk106-gk104-gk110-and-gk112>. Acesso em: 21 jun. 2012.
NYLAND, Lars; HARRIS Mark; PRINS Jan. Fast N-Body Simulation with CUDA. Exemplos CUDA.
O QUE É A TECNOLOGIA de processamento gráfico CUDA?. Disponível em:
<http://www.tecmundo.com.br/10507-o-que-e-a-tecnologia-de-processamento- grafico-cuda.htm>. Acesso em: 14 set. 2011.
O QUE É COMPUTAÇÃO via GPU?. Traduzido por: Google Tradutor. Disponível
em: <http://www.NVIDIA.com/object/GPU_Computing.html>. Acesso em: 15 set. 2011.
O que é computação com GPU?. Disponível Em:
<http://www.NVIDIA.com.br/object/what-is-gpu-computing-br.html>. Acesso em: 02 out. 2012.
O que são STREAM PROCESSORS?. 2007. Disponível Em: <http://forum.gamevicio.com/i/topicos/52/52403-stream-processor-entenda-mais- sobre-este-assunto/index.html>. Acesso em: 10 set. 2012.
Petrobras monta supercomputador mais rápido do Brasil. 2011. Disponível Em:
<http://www.techtudo.com.br/noticias/noticia/2011/11/petrobras-monta- supercomputador-mais-rapido-do-brasil.html>. Acesso em: 25 dez. 2012
PFISTER, Greg. Supercomputadores de baixo custo estão com os dias
contados. 2010. Disponível Em:
<http://www.inovacaotecnologica.com.br/noticias/noticia.php?artigo=supercomputad ores-baixo-custo-gpu&id=010150101109>. Acesso em: 10 jul. 2012.
QUIMICA COMPUTACIONAL. Disponível em: <http://www.NVIDIA.com.br/object/computational_chemistry_br.html>. Acesso em: 25 mar. 2012.
SANTOS, Fábio. GPU dos games à computação científica. 2011. Disponível Em:
<http://www.notasemcfd.com/2011/01/gpu-dos-games-computacao-cientifica.html>. Acesso em: 18 jul. 2012.
STEREOSCOPIC 3D Related News Coming from Computex 2010. 2010.
Disponível Em: <http://3dvision-blog.com/tag/geforce-gtx-465/>. Acesso em: 28 out. 2012.
SUPERCOMPUTADOR Chinês torna-se o mais rápido do mundo. Disponível em:
<http://NVIDIA.adrenaline.uol.com.br/tecnologia/noticias/6589/supercomputador- chines-torna-se-o-mais-rapido-do-mundo.html>. Acesso em: 27 mar. 2012.
SUPERCOMPUTADOR de mesa atinge 12 teraflops. 2009. Disponível Em:
<http://adrenaline.uol.com.br/tecnologia/noticias/3716/supercomputador-de-mesa- atinge-12-teraflops.html>. Acesso em: 11 ago. 2012.
SUPERCOMPUTADOR Titan opera com mais de 18 mil GPUs NVIDIA. 2012.
Disponível Em:
<http://NVIDIA.adrenaline.uol.com.br/tecnologia/noticias/14442/supercomputador- titan-opera-com-mais-de-18-mil-gpus-NVIDIA.html>. Acesso em: 03 nov. 2012. TANENBAUM, Andrew S. Organização Estruturada de Computadores. 5.ed. São Paulo: Pearson Prentice Hall, 2007.
TAVARES, Arnaldo. Especialista da NVIDIA fala sobre processamento paralelo
na USP. São Paulo, 2011. Disponível Em:
<http://www.NVIDIA.com.br/object/prbr_030111a.html>. Acesso em: 25 ago. 2012. TEIXEIRA, Sérgio. A era da computação verde. 2007. Disponível Em: <http://planetasustentavel.abril.com.br/noticia/desenvolvimento/conteudo_238522.sht ml>. Acesso em: 20 mai. 2012.
THE SMX core. Disponível Em: <http://techreport.com/review/22989/a-brief-look-at-
NVIDIA-gk110-graphics-chip/2>. Acesso em: 20 out. 2012.
TOP500. Disponível em: <http://www.top500.org>. Acesso em: 15 set. 2011.
Tudo sobre Arquitetura ATI vs Nvidia (Stream Processor). 2009. Disponível Em:
<http://www.hardware.com.br/comunidade/processors-stream/1013219/>. Acesso em: 25 dez. 2012.
VOLPATO, Diego G. Exploração de Diferentes Níveis de Paralelismo Visando a
Redução da Área de Processadores Embarcados. Porto Alegre, 2011. Disponível
Em:
<http://www.lume.ufrgs.br/bitstream/handle/10183/37167/000819607.pdf?sequence= 1>. Acesso em: 26 mar. 2012.
YAMASHIRO, Fábio M; CORREA, Felipe. Paralelismo em Nível de Instrução. Disponível Em: <http://www.ic.unicamp.br/~ducatte/mo401/1s2012/T2/G01-120437- 123789-134097-t2.pdf>. Acesso em: 14 jul. 2012.
OBRAS CONSULTADAS
COMPUTAÇÃO de alto desempenho utilizando CUDA. Disponível em:
<http://www.brunocardoso.cc/cuda/cuda.pdf>. Acesso em: 15 set 2011.
CUDA – A Revolução Esperada. Disponível em: <http://www.pcmanias.com/cuda-
a-revoluo-esperada>. Acesso em: 16 set 2011.
CUDA, Supercomputação para as Massas. Traduzido por: Google Tradutor.
Disponível em: <http://drdobbs.com/architecture-and-design/207200659>. Acesso em: 12 set 2011.
DALLALANA, Frederico José Camiloti. Uso das GPU para sistemas de
Computação de Alto Desempenho. São José do Rio Preto. Disponível em:
<http://www.dcce.ibilce.unesp.br/~aleardo/cursos/hpc/Fred.pdf>. Acesso em: 15 set 2011.
GPU – Graphics Processing Unit. Disponível em:
<http://www.ic.unicamp.br/~rodolfo/Cursos/mc722/2s2008/Trabalho/g26_texto.pdf>. Acesso em: 15 set 2011.
GPU Computing in Nuclear Engineering. Disponível Em: <http://verl.npre.illinois.edu/AdvancedComputing.html>. Acesso em: 8 jul 2012.
GPU: Aspectos Gerais. Disponível em: <http://pt.scribd.com/doc/52491224/Artigo-
GPU>. Acesso em: 14 set 2011.
KIRK, David B; HWU, Wen-mei W. Programming Massively Parallel Processors. United States of America, 2010. Elsevier.
LAÍS, Aline. Green Computing Computacao Sustentavel. 2012. Disponível Em: <http://cjr.org.br/2012/04/green-computing-computacao-sustentavel>. Acesso em: 16 jun 2012.
MAILLARD, N; NAVAUX, Philippe O. A. Novos rumos em programação
para a exploração de paralelismo multi-nível. Disponível Em: <http://www.ic.unicamp.br/~cmbm/desafios_SBC/maillardnavaux.pdf>. Acesso em: 27 jul 2012.
MORGAN, Timothy Prickett. NVIDIA's Kepler pushes parallelism up to eleven.
2012. Disponível Em:
<http://www.theregister.co.uk/2012/05/15/NVIDIA_kepler_tesla_gpu_revealed>. Acesso em: 22 jul 2012.
ORGANIZAÇÃO e Arquitetura de Computadores. Disponível em: <http://www.inf.ufsc.br/~mario/oac.pdf>. Acesso em: 23 out 2011.
ANEXOS
ANEXO A - Cálculo de Números Perfeitos, CUDA/C
#include <stdio.h> #include <cuda.h> #include <time.h> #include <windows.h> #include "temp.h"
__global__ void perfect(int *a, int N, int max, int threads) {
int idx = blockIdx.x * blockDim.x + threadIdx.x; int soma, b, trab, i;
trab = max/threads; for (i=0; i<trab; i++) {
if (idx%2==0) { soma=0; for (b=1; b<(idx/2)+1; b++) { if (idx%b==0) { soma = soma + b; } } if (soma==idx) { a[idx] = idx; } } idx +=threads; } }
int main(int argc, char *argv) { int limit;
printf ("\nNumeros PERFEITOS Usando CUDA\n Testar ate qual valor?\n");
scanf ("%d", &limit);
int *a_h=0; // pointeiro da RAM
int *a_d=0; // pointeiro da GPU
struct timeval tempo1, tempo2; long elapsed_mtime;
gettimeofday(&tempo1, NULL); int n_blocks = 32;
int block_size = 1024;
const int N = n_blocks*block_size;// tamanho do vetor int i;
int size = N * sizeof(int); // qtde de bytes do vetor a_h = (int *)malloc(size);
for (i=0; i<N; i++) a_h[i] = 0;
cudaMalloc((void**)&a_d, size); cudaMemset(a_d, 0, size);
cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice); //printf("\n\nQt de blocos: %d",n_blocks);
//printf("\ntamanho do bloco: %d\n\n", block_size); //executa o kernel na GPU
perfect <<< n_blocks, block_size >>> (a_d, N, limit, n_blocks*block_size);
// copia da GPU para a RAM
cudaMemcpy(a_h, a_d, size, cudaMemcpyDeviceToHost); gettimeofday(&tempo2, NULL);
for (i=0; i<N; i++) if (a_h[i] != 0)
printf("\nN. Perfeito: %d", a_h[i]); //libera memorias
free(a_h); cudaFree(a_d);
elapsed_mtime = ((tempo2.tv_sec - tempo1.tv_sec) * 1000 + (tempo2.tv_usec - tempo1.tv_usec)/1000.0) + 0.5;
printf("\nElapsed time = %ld milliseconds\n", elapsed_mtime); }
ANEXO A1 - Cálculo De Números Perfeitos, C
#include <stdio.h> #include "tempo.h" #include <pthread.h> typedef struct { int id, inicio, fim; }thread_info;
void *perfect(void *arg);
void main(int argc, char *argv[]){ int limit, num_threads, trab;
printf ("\nNúmeros PERFEITOS!\nUsando pThread\n"); printf ("\nTestar até qual valor? ");
scanf ("%d", &limit);
printf ("Executar com quantas Threads? "); scanf ("%d", &num_threads); trab = limit/num_threads; pthread_t thread_id[num_threads]; thread_info t_info[num_threads]; int i = 0; //Cria as threads tempo1();
for(i=0; i<num_threads; i++){ t_info[i].id = i;
if (i!=0) t_info[i].inicio = t_info[i-1].fim; else t_info[i].inicio = 2; if (i==num_threads-1) t_info[i].fim = limit; else t_info[i].fim = t_info[i].inicio+trab;
pthread_create(&(thread_id[i]), NULL, perfect, (void *)&(t_info[i]));
}
for(i=0; i<num_threads; i++){
pthread_join(thread_id[i], NULL); }
tempo2();
tempoFinal("mili segundos", "tempo", MSGLOG); }
void *perfect(void *arg){ int soma, i, b;
thread_info *thi = (thread_info *) arg; for (i=thi->inicio; i<=thi->fim; i++) {
soma=0; if (i%2==0) { for (b=1; b<(i/2)+1; b++) { if (i%b==0) { soma = soma + b; } } if (soma==i) {
printf("Thread %d - Nº Perfeito: %d\n", thi- >id, i);
} }
} }
ANEXO A2 - Cálculo de Números Primos, CUDA/C
#include <stdio.h> #include <cuda.h> #include <time.h> #include <windows.h> #include "temp.h"
__global__ void prime(int *a, int N, int max, int threads) {
int idx = (blockIdx.x * blockDim.x) + threadIdx.x; int trab, i, c;
trab = max/threads; for (i=0; i<trab; i++) {
for ( c = 2 ; c <= idx - 1 ; c++ ) { if ( idx%c == 0 ) break; } if ( c == idx )
{ a[idx] = idx; } idx +=threads; } }
int main(int argc, char *argv) { int limit;
printf ("\nNumeros PRIMOS Usando CUDA\n Testar ate qual valor?\n"); scanf ("%d", &limit);
int *a_h=0; // pointeiro da RAM
int *a_d=0; // pointeiro da GPU
struct timeval tempo1, tempo2; long elapsed_mtime;
gettimeofday(&tempo1, NULL); int n_blocks = 32;
int block_size = 1024;
const int N = limit; // tamanho do vetor
int i;
int size = N * sizeof(int); // qtde de bytes do vetor a_h = (int *)malloc(size);
for (i=0; i<N; i++) a_h[i] = 0;
cudaMalloc((void**)&a_d, size); cudaMemset(a_d, 0, size);
//copia da RAM para a GPU
cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice); //printf("\n\nQt de blocos: %d",n_blocks);
//printf("\ntamanho do bloco: %d\n\n", block_size); //executa o kernel na GPU
prime <<< n_blocks, block_size >>> (a_d, N, limit, n_blocks*block_size);
// copia da GPU para a RAM
cudaMemcpy(a_h, a_d, size, cudaMemcpyDeviceToHost); gettimeofday(&tempo2, NULL);
for (i=0; i<N; i++) if (a_h[i] > 0)
printf("\nN. Primo: %d", a_h[i]); //libera memorias
free(a_h); cudaFree(a_d);
elapsed_mtime = ((tempo2.tv_sec - tempo1.tv_sec) * 1000 + (tempo2.tv_usec - tempo1.tv_usec)/1000.0) + 0.5;
}
ANEXO A3 - Cálculo de Números Primos, C
#include <stdio.h> #include "tempo.h" #include <pthread.h> typedef struct { int id, inicio, fim; }thread_info;
void *perfect(void *arg);
void main(int argc, char *argv[]){ int limit, num_threads, trab;
printf ("\nNúmeros PRIMOS!\nUsando pThread\n"); printf ("\nTestar até qual valor? ");
scanf ("%d", &limit);
printf ("Executar com quantas Threads? "); scanf ("%d", &num_threads); trab = limit/num_threads; pthread_t thread_id[num_threads]; thread_info t_info[num_threads]; int i = 0; //Cria as threads tempo1();
for(i=0; i<num_threads; i++){ t_info[i].id = i; if (i!=0) t_info[i].inicio = t_info[i-1].fim; else t_info[i].inicio = 2; if (i==num_threads-1) t_info[i].fim = limit; else t_info[i].fim = t_info[i].inicio+trab;
pthread_create(&(thread_id[i]), NULL, perfect, (void *)&(t_info[i]));
}
for(i=0; i<num_threads; i++){
pthread_join(thread_id[i], NULL); }
tempo2();
tempoFinal("mili segundos", "tempo", MSGLOG); }
void *perfect(void *arg){ int soma, i, b, c;
thread_info *thi = (thread_info *) arg; for (i=thi->inicio; i<=thi->fim; i++) { for ( c = 2 ; c <= i - 1 ; c++ ) {
if ( i%c == 0 ) break;
}
if ( c == i ) {
printf("Thread %d - Nº Primo: %d\n", thi->id, i); }
} }
ANEXO A4 - Parte do Código de Multiplicação De Matrizes, CUDA/C Fonte: Exemplos CUDA
// CUBLAS version 2.0 { cublasHandle_t handle; cublasStatus_t ret; ret = cublasCreate(&handle); if (ret != CUBLAS_STATUS_SUCCESS) {
printf("cublasCreate returned error code %d, line(%d)\n", ret, __LINE__);
shrQAFinishExit(argc, (const char **)argv, QA_FAILED); }
const float alpha = 1.0f; const float beta = 0.0f;
//Perform warmup operation with cublas
ret = cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,
matrix_size.uiWB, matrix_size.uiHA, matrix_size.uiWA, &alpha, d_B, matrix_size.uiWB, d_A, matrix_size.uiWA, &beta, d_C, matrix_size.uiWA);