ajustenasdimensÕesde kernels para ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de...

99
UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ DEPARTAMENTO ACADÊMICO DE COMPUTAÇÃO CURSO DE BACHARELADO EM CIÊNCIA DA COMPUTAÇÃO JOÃO MARTINS DE QUEIROZ FILHO AJUSTE NAS DIMENSÕES DE KERNELS PARA DISPOSITIVOS ACELERADORES COM BASE NA ANÁLISE DE CARACTERÍSTICAS ARQUITETURAIS E NA UTILIZAÇÃO DE FERRAMENTA DE AUTOTUNING MONOGRAFIA CAMPO MOURÃO 2018

Upload: others

Post on 03-Oct-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁDEPARTAMENTO ACADÊMICO DE COMPUTAÇÃO

CURSO DE BACHARELADO EM CIÊNCIA DA COMPUTAÇÃO

JOÃO MARTINS DE QUEIROZ FILHO

AJUSTE NAS DIMENSÕES DE KERNELS PARADISPOSITIVOS ACELERADORES COM BASE NA

ANÁLISE DE CARACTERÍSTICASARQUITETURAIS E NA UTILIZAÇÃO DE

FERRAMENTA DE AUTOTUNING

MONOGRAFIA

CAMPO MOURÃO2018

Page 2: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

JOÃO MARTINS DE QUEIROZ FILHO

AJUSTE NAS DIMENSÕES DE KERNELS PARADISPOSITIVOS ACELERADORES COM BASE NA

ANÁLISE DE CARACTERÍSTICASARQUITETURAIS E NA UTILIZAÇÃO DE

FERRAMENTA DE AUTOTUNING

Trabalho de Conclusão de Curso de Graduaçãoapresentado à disciplina de Trabalho de Conclusãode Curso 2, do Curso de Bacharelado em Ciênciada Computação do Departamento Acadêmico deComputação da Universidade Tecnológica Federal doParaná, como requisito parcial para obtenção do títulode Bacharel em Ciência da Computação.

Orientador: Prof. Dr. Rogério Aparecido Gonçalves

CAMPO MOURÃO2018

Page 3: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Ministério da EducaçãoUniversidade Tecnológica Federal do Paraná

Câmpus Campo MourãoCurso de Bacharelado em Ciência da Computação

ATA DE DEFESA DO TRABALHO DE CONCLUSÃO DE CURSO

Às 13:50 do dia 20 de junho de 2018 foi realizada na sala E003 da UTFPR-CM a sessão pública

da defesa do Trabalho de Conclusão do Curso de Bacharelado em Ciência da Computação do(a) aca-

dêmico(a) João Martins de Queiroz Filho com o título Ajuste nas dimensões de Kernel para

dispositivos aceleradores com base na análise de características arquiteturais e na utilização

de ferramenta de autotuning. Estavam presentes, além do(a) acadêmico(a), os membros da banca

examinadora composta por: Prof. Dr. Rogério Aparecido Gonçalves (orientador), Prof. Ms. Ju-

liano Henrique Foleiss e Prof. Dr. Frank Helbert Borsato. Inicialmente, o(a) acadêmico(a) fez a

apresentação do seu trabalho, sendo, em seguida, arguido(a) pela banca examinadora. Após as arguições,

sem a presença do(a) acadêmico(a), a banca examinadora o(a) considerou na disciplina

de Trabalho de Conclusão de Curso 2 e atribuiu, em consenso, a nota ( ).

Este resultado foi comunicado ao(à) acadêmico(a) e aos presentes na sessão pública. A banca examina-

dora também comunicou ao acadêmico(a) que este resultado fica condicionado à entrega da versão final

dentro dos padrões e da documentação exigida pela UTFPR ao professor Responsável do TCC no prazo

de onze dias. Em seguida foi encerrada a sessão e, para constar, foi lavrada a presente Ata que segue

assinada pelos membros da banca examinadora, após lida e considerada conforme.

Observações:

Campo Mourão, 20 de junho de 2018

Prof. Ms. Juliano Henrique Foleiss Prof. Dr. Frank Helbert BorsatoMembro 1 Membro 2

Prof. Dr. Rogério AparecidoGonçalvesOrientador

A ata de defesa assinada encontra-se na coordenação do curso.

Câmpus Campo Mourão Via Rosalina Maria do Santos, 1233

CEP 87301-899 Caixa Postal: 271 Campo Mourão - PR - Brasil

Telefone Geral +55 (44) 3518-1400

Page 4: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Agradecimentos

Aos meus pais pelo amor, dedicação, sendo meus guias em todos os meus momentos, o apoioincondicional e motivação fizeram com que terminasse esta graduação.

A Universidade Tecnológica Federal do Paraná, a todos os professores do Departa-mento de Ciência da Computação pela paciência e dedicação em ensinarem todo o conteúdopara sermos excelentes profissionais.

Ao meu orientador, o professor Rogério Aparecido Gonçalves, que se tornou umamigo valioso e que tenho muito estimo, sem sua orientação e motivação não teria terminadoesta Monografia.

Aos amigos por terem me apoiado e ficarem ao meu lado nas horas que eu maisprecisava. Em especial a uma amiga com nome de anjo que me apoiou e motivou nosmomentos mais difíceis da graduação, a você todo meu carinho e admiração.

A professora Vanessa Sehaber pela ajuda em Estatística.E a todos que direta ou indiretamente fizeram parta da minha formação, o meu

muito obrigado.

Page 5: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Resumo

Queiroz Filho, J. M. Ajuste nas dimensões de kernels para dispositivos aceleradores combase na análise de características arquiteturais e na utilização de ferramenta de Autotuning.2018. 97. f. Monografia (Curso de Bacharelado em Ciência da Computação), UniversidadeTecnológica Federal do Paraná. Campo Mourão, 2018.

Atualmente há uma lacuna de desempenho entre Unidade Central de Processamento (CPU)e Unidade de Processamento Gráfico (GPU), esta lacuna fez com que desenvolvedorestenham o interesse por aplicações que exploram o trabalho conjunto entre CPUs e GPUs.Contudo para criar essas aplicações os desenvolvedores encontram desafios, desde transformarcódigo legado para sistemas multicores até encontrar a configuração ideal para a arquiteturado dispositivo alvo. Desta forma, este trabalho tem como objetivo analisar por meio deferramentas de autotuning de software a escolha de configurações para o arranjo de threads,na tentativa de extrair o melhor desempenho para dispositivos aceleradores, neste caso GPUs.Para alcançar esse objetivo foi utilizado um subconjunto de algoritmos da família Polybech,KernelGen e NVIDIA CUDA Samples que tiveram seus kernels testados com a ferramenta deautotuning OpenTuner. Os benchmarks foram executados e resultados de algumas métricasforam coletados utilizando a ferramenta de perfilamento nvprof da NVIDIA para a escolhada melhor configuração para cada contexto. Os resultados sugerem que o meio mais eficientepara se encontrar a melhor configuração para a arquitetura é utilizando ferramentas deautotuning, pois para determinados tamanhos torna-se inviável a escolha da configuração pormeio de busca exaustiva ou por escolhas aleatórias.Palavras-chaves: Computação Paralela, Computação Heterogênea, GPGPU, otimização decódigo e ferramentas de autotuning

Page 6: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Abstract

Queiroz Filho, J. M. Adjusting the dimensions of kernels for accelerator devices based on theanalysis of architectural features and the use of the Autotuning tool. 2018. 97. f. Monograph(Undergradute Program in Computer Science), Federal University of Technology – Paraná.Campo Mourão, PR, Brazil, 2018.

Currently there is a performance gap between the Central Processing Unit (CPU) andthe Graphics Processing Unit (GPU), this gap has made developers have an interest inapplications that exploit the joint work between CPUs and GPUs. However, to create suchapplications developers face challenges ranging from transforming legacy code to multicoresystems until they find the optimal configuration for the target device architecture. In thisway, this work has as its objective to analyze the choice of configurations for the arrangementof threads. We are using software tools in an attempt to extract the best performancefor device accelerators, in this case GPUs. To achieve this goal a set of algorithms of thePolybench, KernelGen and NVIDIA Samples were used which had their kernels tested withthe OpenTuner autotuning tool. Benchmarks were executed and the results of some metricswere collected using nvprof NVIDIA’s profiling tool to choose the best configuration for eachcontext. The results suggest that the most efficient way to find the best configuration for thearchitecture is to use autotuning tools, because for certain sizes it becomes impracticable tochoose the configuration through exhaustive search or random choices.Keywords: Parallel Computing. Heterogeneous Computing. GPGPU. code optimizationand autotuning tools

Page 7: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Lista de figuras

1.1 Diferença de performance entre GPUs e CPUs. Fonte: (NVIDIA, 2017) . . 14

2.1 Sistema heterogêneo CPU e FPGA. Fonte: (BRODTKORB et al., 2010) . . 192.2 Layout lógico do coprocessador Intel Xeon Phi. Fonte: (RAHMAN, 2013) . 202.3 Modelo da arquitetura Fermi. Fonte: (NVIDIA, 2009) . . . . . . . . . . . . 212.4 Fermi Streaming Multiprocessor (SM). Fonte: (NVIDIA, 2009) . . . . . . . 222.5 Diagrama completo arquitetura Kepler. Fonte: (NVIDIA, 2012) . . . . . . . 232.6 Kepler Streaming Multiprocessor (SM). Fonte: (NVIDIA, 2012) . . . . . . . 242.7 Arquitetura Pascal completa com 60 unidades Streaming Multiprocessor (SM ).

Fonte: (NVIDIA, 2016) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252.8 Pascal unidade SM. Fonte: (NVIDIA, 2016) . . . . . . . . . . . . . . . . . . 262.9 Fluxo de execução de um código em Compute Unified Device Architecture

(CUDA). Fonte: (CHENG et al., 2014) . . . . . . . . . . . . . . . . . . . . . 272.10 Divisão hierárquica de grids, blocos e threads. Fonte: (CHENG et al., 2014) 282.11 Mapeamento da visão lógica para o hardware . . . . . . . . . . . . . . . . . . 292.12 Organização do arranjo de threads . . . . . . . . . . . . . . . . . . . . . . . . 292.13 Funcionamento do OpenTuner. Fonte: (ANSEL et al., 2014) . . . . . . . . . 352.14 Modelo de divisão de trabalho das técnicas de busca. Fonte: (ANSEL et al.,

2014) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362.15 Processo de geração da função objetiva. Fonte: (STORN, 1996) . . . . . . . 372.16 Funcionamento do algoritmo de busca Particle Swarm Optimization, em um

espaço de busca 2D. Fonte: (ROBINSON; RAHMAT-SAMII, 2004) . . . . . 382.17 Demonstração do Algoritmo de busca Hill Climbing. Fonte: (RUSSELL;

NORVIG, 2003) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

4.1 Etapas para a realização da pesquisa . . . . . . . . . . . . . . . . . . . . . . 484.2 Arquiteturas que serão utilizadas nos experimentos . . . . . . . . . . . . . . 57

5.1 Estatísticas de uso de instruções por ciclo. Fonte: (NVIDIA, 2015b) . . . . 705.2 Comparação entre os testes e os valores encontrados para a métrica gld_efficiency 765.3 Variação entre as configurações e a métrica achieved_occupancy para os

dispositivos TitanX e GTX-780 . . . . . . . . . . . . . . . . . . . . . . . . . . 81

Page 8: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

5.4 Variação entre as configurações e a métrica achieved_occupancy para osdispositivos TitanX e GTX-780 . . . . . . . . . . . . . . . . . . . . . . . . . . 84

5.5 Valores encontrados segundo a métrica sm_efficiency . . . . . . . . . . . . . 895.6 Densidade de valores entre 80% a 100% . . . . . . . . . . . . . . . . . . . . . 905.7 Melhores resultados para a métrica sm_efficiency . . . . . . . . . . . . . . . 91

Page 9: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Lista de tabelas

3.1 Configurações válidas para um determinado número de iterações . . . . . . . 423.2 Configurações válidas para o número de iterações 𝑁 = 64 . . . . . . . . . . . 423.3 Versões de kernels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463.4 Número de operações realizadas para o cálculo do 𝑖𝑑 global das threads . . . 47

5.1 Resultados do Experimento soma de vetor . . . . . . . . . . . . . . . . . . . 615.2 Média de warps ativos na execução do algoritmo sincos . . . . . . . . . . . . 625.3 Média de warps ativos na execução do algoritmo sincos . . . . . . . . . . . . 625.4 Sincos métrica gld_efficiency GPU-TitanX . . . . . . . . . . . . . . . . . . . 665.5 Sincos métrica gld_efficiency GPU-GTX-1070 . . . . . . . . . . . . . . . . . . 665.6 Sincos métrica gld_efficiency GPU-GTX-780 . . . . . . . . . . . . . . . . . . . 675.7 Sincos métrica gst_efficiency GPU-TitanX . . . . . . . . . . . . . . . . . . . 675.8 Sincos métrica gst_efficiency GPU-GTX-1070 . . . . . . . . . . . . . . . . . . 685.9 Sincos métrica gst_efficiency GPU-GTX-780 . . . . . . . . . . . . . . . . . . . 685.10 Sincos métrica inst_per_warp GPU-TitanX . . . . . . . . . . . . . . . . . . . 695.11 Sincos métrica inst_per_warp GPU-GTX-1070 . . . . . . . . . . . . . . . . . 695.12 Sincos métrica inst_per_warp GPU-GTX-780 . . . . . . . . . . . . . . . . . . 695.13 Sincos métrica ipc GPU-TitanX . . . . . . . . . . . . . . . . . . . . . . . . . 705.14 Sincos métrica ipc GPU-GTX-1070 . . . . . . . . . . . . . . . . . . . . . . . . 715.15 Sincos métrica ipc GPU-GTX-780 . . . . . . . . . . . . . . . . . . . . . . . . . 715.16 Sincos métrica achieved_occupancy GPU-TitanX . . . . . . . . . . . . . . . . 725.17 Sincos métrica achieved_occupancy GPU-GTX-1070 . . . . . . . . . . . . . . . 725.18 Sincos métrica achieved_occupancy GPU-GTX-780 . . . . . . . . . . . . . . . 725.19 Sincos métrica sm_efficiency GPU-TitanX . . . . . . . . . . . . . . . . . . . 735.20 Sincos métrica sm_efficiency GPU-GTX-1070 . . . . . . . . . . . . . . . . . . 735.21 Sincos métrica sm_efficiency GPU-GTX-780 . . . . . . . . . . . . . . . . . . . 745.22 GENERAL MATRIX MULTIPLY (GEMM ) métrica gld_efficiency GPU-TitanX 755.23 GEMM métrica gld_efficiency GPU-GTX-1070 . . . . . . . . . . . . . . . . . 755.24 GEMM métrica gld_efficiency GPU-GTX-780 . . . . . . . . . . . . . . . . . . 755.25 GEMM métrica gst_efficiency GPU-TitanX . . . . . . . . . . . . . . . . . . . 775.26 GEMM métrica gst_efficiency GPU-GTX-1070 . . . . . . . . . . . . . . . . . 77

Page 10: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

5.27 GEMM métrica gst_efficiency GPU-GTX-780 . . . . . . . . . . . . . . . . . . 785.28 GEMM métrica inst_per_warp GPU-TitanX . . . . . . . . . . . . . . . . . . 785.29 GEMM métrica inst_per_warp GPU-GTX-1070 . . . . . . . . . . . . . . . . . 785.30 GEMM métrica inst_per_warp GPU-GTX-780 . . . . . . . . . . . . . . . . . 785.31 GEMM métrica ipc GPU-TitanX . . . . . . . . . . . . . . . . . . . . . . . . . 795.32 GEMM métrica ipc GPU-GTX-1070 . . . . . . . . . . . . . . . . . . . . . . . 795.33 GEMM métrica ipc GPU-GTX-780 . . . . . . . . . . . . . . . . . . . . . . . . 805.34 GEMM métrica occupancy GPU-TitanX . . . . . . . . . . . . . . . . . . . . . 805.35 GEMM métrica occupancy GPU-GTX-780 . . . . . . . . . . . . . . . . . . . . 805.36 GEMM métrica sm_efficiency GPU-TitanX . . . . . . . . . . . . . . . . . . . 825.37 GEMM métrica sm_efficiency GPU-GTX-1070 . . . . . . . . . . . . . . . . . 825.38 GEMM métrica sm_efficiency GPU-GTX-780 . . . . . . . . . . . . . . . . . . 835.39 Melhores configurações por força-bruta para a métrica sm_efficiency . . . . 865.40 Dez Maiores e dez menores valores com base na métrica sm_efficiency . . . 875.41 Parte dos testes realizado por força-bruta para a métrica sm_efficiency . . . 875.42 Teste por força-bruta métrica sm_efficiency . . . . . . . . . . . . . . . . . . 88

Page 11: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Siglas

API: Interface de Programação de AplicativosATLAS: Automatically Tunned Linear Algebra SoftwareCPU: Unidade Central de ProcessamentoCPUs: Unidades Centrais de ProcessamentoCUDA: Compute Unified Device ArchitectureFPGA: Arranjo de Portas ProgramáveisFPGAs: Arranjos de Portas ProgramáveisGEMM: General Matrix MultiplyGFLOPS: Bilhões de Operações em Ponto Flutuante por SegundoGPC: Graphics Processing ClustersGPU: Unidade de Processamento GráficoGPUs: Unidades de Processamento GráficoLLVM: Low Level Virtual MachineMIMD: Multiple Instruction, Multiple DataSFU: Unidades Funcionais EspeciaisSIMD: Single Instruction, Multiple DataSIMT: Single Instruction, Multiple ThreadsSISD: Single Instruction, Single DataSM: Streaming MultiprocessorTPC: Texture Processing Clusters

Page 12: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Sumário

1 Introdução 121.1 Considerações preliminares . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.2 Problema de Pesquisa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131.3 Abordagem Proposta e Metodologia . . . . . . . . . . . . . . . . . . . . . . . 141.4 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151.5 Principais Contribuições . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151.6 Organização do Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2 Referencial Teórico 172.1 Modelos de programação paralela . . . . . . . . . . . . . . . . . . . . . . . . 172.2 Dispositivos Aceleradores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.2.1 Arranjo de Portas Programáveis (FPGA) . . . . . . . . . . . . . . . . 182.2.2 Intel Xeon Phi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.2.3 Unidades de Processamento Gráfico (GPU) . . . . . . . . . . . . . . . 20

2.3 Modelo de Programação (CUDA) . . . . . . . . . . . . . . . . . . . . . . . . 252.4 Autotuning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

2.4.1 OpenTuner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352.5 Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

3 Estudo sobre Ajustes nas Dimensões de Kernels 403.1 Ajustes do lado do hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . 413.2 Ajustes do lado do software . . . . . . . . . . . . . . . . . . . . . . . . . . . 433.3 Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4 Metodologia 484.1 Uso dos benchmarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

4.1.1 Algoritmo Soma de Vetores - sumvector . . . . . . . . . . . . . . . . 494.1.2 Algoritmo GEMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504.1.3 Algoritmo de Cálculo da Tabela de Senos e Cossenos –sincos . . . . . 52

4.2 Desenvolvimento dos scripts para as execuções com o OpenTuner . . . . . . . 524.3 Realização dos Testes e Extração da Melhor Configuração . . . . . . . . . . . 574.4 Detecção de Padrões ou Tendências de Configuração . . . . . . . . . . . . . . 58

Page 13: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

4.5 Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

5 Experimentos e Resultados 605.1 Primeiros Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

5.1.1 Experimento com execuções avulsas para o Soma de Vetores . . . . 605.1.2 Experimento com execuções avulsas para o sincos . . . . . . . . . . 625.1.3 Experimentos iniciais de automatização por força bruta . . . . . . . . 63

5.2 Experimentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655.2.1 Experimento 1 com OpenTuner: Sincos . . . . . . . . . . . . . . . . . 655.2.2 Experimento 2 com OpenTuner: GEMM . . . . . . . . . . . . . . . . 745.2.3 Experimento 3: Experimento força-bruta GEMM . . . . . . . . . . . 835.2.4 Experimento 4: Experimento força-bruta Sincos . . . . . . . . . . . . 885.2.5 Resultados obtidos para Detecção e Tendências de Configuração . . . 89

5.3 Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

6 Conclusões 926.1 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

Referências 95

Page 14: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Capítulo

1Introdução

Ao longo dos últimos anos houve uma grande evolução na área de Computação Paralela. Emespecífico, na computação paralela com elementos heterogêneos e na utilização de dispositivosaceleradores, como as Unidades de Processamento Gráfico (GPUs), Arranjos de PortasProgramáveis (FPGAs) e arranjos de coprocessadores.

Com a introdução de GPUs e do modelo de programação da plataforma de computaçãoparalela CUDA, pela primeira vez, esses coprocessadores gráficos extremamente poderosospuderam ser usados por programadores C para trabalhos computacionalmente caros (COOK,2013). Este trabalho tem como objetivo apresentar o contexto geral do desenvolvimento deaplicações em paralelo para dispositivos aceleradores. Um dos objetivos iniciais era mostraras dificuldades no desenvolvimento de aplicações para GPUs quanto à escolha ou definiçãodas dimensões do domínio do problema. Queríamos verificar a existência de um padrãona definição das configurações de execução que pudesse ser utilizado na escolha da melhorconfiguração, propondo uma solução para o problema de ajuste de kernels para dispositivosaceleradores, no caso Unidade de Processamento Gráfico (GPU).

1.1. Considerações preliminaresMicroprocessadores que possuíam um único núcleo, os conhecidos processadores (single core)das famílias do Intel Pentium (GREER; HENRY, 1997) e AMD Opteron (CONWAY et al.,2010), impulsionaram o aumento de desempenho para uma escala de Bilhões de Operações emPonto Flutuante por Segundo (GFLOPS). Esse contínuo avanço fez com os desenvolvedoresde software acreditassem nos avanços do hardware para aumentar o desempenho de suaaplicação (KIRK; HWU, 2010).

Contudo a partir de 2003, os microprocessadores atingiram uma limitação em seudesempenho. Questões relacionadas ao consumo de energia e dissipação de calor chegaram a

12

Page 15: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

13

um estado crítico, que limitou fisicamente o aumento da frequência de clock, consequentementeessa limitação impactou no número de instruções que podiam ser executadas a cada ciclo declock (KIRK; HWU, 2010).

Essa limitação de velocidade de clock levou os fabricantes de microprocessadoresaos projetos de arquiteturas com múltiplos núcleos, as arquiteturas multicore. Como umatentativa de aumento do poder de processamento apostando no paralelismo entre tarefas. Apartir desta mudança os desenvolvedores criaram o conceito de Revolução da Concorrência(SUTTER; LARUS, 2005), que é a utilização de várias threads que cooperam entre si ecompletam um determinado trabalho mais rapidamente.

Atualmente, um outro conceito presente é o de Aceleração de Aplicações, no qualo código é preparado para fazer uso de novos recursos disponíveis nas plataformas, comoinstruções de vetorização (INTEL, 2015) ou para lançar a execução de algumas partes docódigo (kernels) em dispositivos aceleradores (offloading). Esses dispositivos aceleradores emconjunto com Unidades Centrais de Processamento (CPUs) multicore podem aumentar odesempenho das aplicações explorando o potencial paralelismo.

Entre os aceleradores estão hardwares com arquiteturas reconfiguráveis, como osFPGAs, as GPUs (GASTER et al., 2011) e arranjos de coprocessadores (INTEL, 2013). AsGPUs tem ganho destaque e tem se popularizado devido ao mercado de entretenimento e dedispositivos móveis. Uso de plataformas englobando CPU-GPU na última década elevaram oparadigma de programação paralela a um novo patamar (CHENG et al., 2014).

1.2. Problema de PesquisaAtualmente há uma lacuna entre o desempenho entre Unidade Central de Processamento(CPU) e GPU, que pode ser visto na Figura 1.1 para aplicações com paralelismo de dados.Esta grande diferença no desempenho tem despertado o interesse de pesquisadores quedesenvolvem aplicações explorando o trabalho conjunto de CPUs e GPUs, dividindo a cargade trabalho entre o elemento principal de processamento CPU e lançando a execução de regiõesde códigos paralelizáveis que podem ser transformadas em kernels para serem aceleradas emGPUs. Esse conceito já está sendo usado em aplicações de propósito geral e científico (KIRK;HWU, 2010).

Para o lançamento da execução de um kernel em uma GPU, é necessário que oprogramador defina a configuração do arranjo de threads em termos das dimensões de grid,blocos e número de threads. A configuração determinará o número total de threads que serãoexecutadas no hardware.

Nesse contexto, o processo de desenvolvimento de software traz aos desenvolvedoresuma série de desafios (GASTER et al., 2011) que buscam a obtenção de aplicações eficientesdo ponto de vista de desempenho e consumo energético. Alguns desses desafios são:

Page 16: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

14

Figura 1.1. Diferença de performance entre GPUs e CPUs. Fonte: (NVIDIA, 2017)

• Transformar código legado que aproveite novos recursos de sistemas multicore proporci-onando uma modernização no código, ou paralelizando aplicações que extrapolam osrecursos de CPUs para usarem dispositivos aceleradores. Estudos preliminares mostramque ferramentas que geram código acabam por fazer escolhas ingênuas ou genéricas.

• Os kits de desenvolvimento fornecidos pelos fabricantes dos dispositivos, ainda não estãoacessíveis, de maneira amigável, para todas as classes de usuários. Existe a necessidadede aprendizado de um novo paradigma de desenvolvimento.

• Os kits abstraem o acesso aos recursos do hardware até certo nível, exigindo que odesenvolvedor declare explicitamente transferências de dados e dimensões do arranjode threads que deve ser criado para a execução do kernel. O que muitas vezes leva autilização de definições genéricas.

• Os desenvolvedores na maioria das vezes escolhem configurações padrões ou aleatóriasque não utilizam todo o desempenho da arquitetura, levando muitas vezes a umdesempenho inferior a um formato de aplicação sequencial.

Neste cenário é evidente que deve-se criar mecanismos que ajuste as melhoresconfigurações com base na arquitetura que está sendo utilizada.

1.3. Abordagem Proposta e MetodologiaPara descobrir a melhor configuração, é necessário realizar testes executando um conjunto debenchmark com as configurações possíveis, sendo que com o número de configurações muitoalto, um teste por força-bruta é descartado.

Em um segundo momento optou-se pela utilização de uma ferramenta de autotuningcomo uma forma de realizar os testes dessas configurações de maneira mais eficiente. Esse

Page 17: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

15

tipo de ferramenta realiza testes automatizados com auxílio de algoritmos de busca paraencontrar a configuração ideal, com base em uma das métricas escolhidas.

Este passo consiste na utilização de versões de kernels dos algoritmos na execuçãocom o conjunto de configurações. Com base no resultado da métrica a ferramenta classifica emantém a configuração que obteve o melhor resultado.

O passo seguinte, após a melhor configuração ser encontrada, seria criar mecanismosque facilitassem o trabalho do desenvolvedor e que o permitissem codificar aplicações maisfacilmente utilizando as configurações mais ajustadas para a arquitetura alvo, extraindo ummelhor desempenho.

1.4. ObjetivosO objetivo deste trabalho é analisar por meio de ferramentas de autotuning, qual a melhormaneira de extrair o melhor desempenho para dispositivos aceleradores GPUs, considerandoa definição da configuração do arranjo de threads.

Inicialmente, tinha-se como objetivo encontrar a melhor configuração e detectarpadrões na escolha dessas configurações que impactassem na obtenção de melhorias dedesempenho. E então, com estabelecer um mecanismo para facilitar a definição deconfigurações do arranjo de threads e consequentemente facilitar o desenvolvimento deaplicações heterogêneas.

1.5. Principais ContribuiçõesNo desenvolvimento desse trabalho foi necessário a criação de scripts para a ferramentaOpenTuner. Como a ferramenta permite ao usuário customizar a execução de testes, expondouma interface e classes para o desenvolvedor. Desta forma, para cada um dos experimentosfoi criado um script em Python.

Cada um dos scripts executavam os benchmarks com as devidas configuraçõese coletavam o resultado para a métrica considerada no teste utilizando o programa deperfilamento nvprof da NVIDIA (NVIDIA, 2015a).

Assim a principal contribuição deste trabalho é deixar um conjunto de scriptsfuncionais e apresentar uma metodologia aplicável de se encontrar configurações de kernelscom auxílio da ferramenta OpenTuner.

1.6. Organização do TextoNeste Capítulo foi introduzido o problema de pesquisa, o contexto do trabalho, bem comoseus objetivos e contribuições. Os trabalhos relacionados são apresentados no Capítulo 2. NoCapítulo 3 é exposto o estudo sobre os ajustes nas dimensões de kernels e neste contexto os

Page 18: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

16

ajustes que devem ser realizados do lado do hardware e software. No Capítulo 4 é mostradocomo foi realizado o desenvolvimento da monografia e o Capítulo 5 apresenta os resultadosobtidos com as execuções dos experimentos. Por fim no Capítulo 6 são apresentadas conclusõesobtidas com base resultados gerados pelo Trabalho de Conclusão de Curso.

Page 19: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Capítulo

2Referencial Teórico

Este capítulo apresenta um referencial teórico a fim de embasar o desenvolvimento destetrabalho. A Seção 2.1 Modelos de programação paralela mostra os termos e classificaçõesexistentes para descrever os tipos de paralelismo e a seção 2.2 Dispositivos Aceleradoresapresenta os principais dispositivos aceleradores utilizados atualmente. As seções 2.3 Modelode Programação CUDA e 2.4 autotuning expõe respectivamente o modelo de programaçãoparalela para GPUs e uma contextualização de como é o funcionamento das ferramentas deautotuning bem como a ferramenta OpenTuner.

2.1. Modelos de programação paralelaNo modelo de programação paralela há alguns termos que descrevem tanto o modelo deprogramação quanto a arquitetura paralela. O trabalho de Flynn (1972) foi um dos primeirosa criar um conjunto classificatório de arquiteturas existentes, seus termos são utilizados atéhoje para descrever o tipo de paralelismo e a arquitetura:

• Single Instruction, Single Data (SISD): funcionamento característico do modelode Von Neumann que corresponde um único fluxo de instruções opera sobre um únicofluxo de dados, não há nenhum paralelismo;

• Single Instruction, Multiple Data (SIMD): corresponde ao processamento devários dados sob o comando de apenas uma instrução.

• Multiple Instruction, Multiple Data (MIMD): múltiplas unidades executamfluxos independentes e separados de instruções em suas unidades de processamento.

Há outras classificações que divide as máquinas segundo o compartilhamento dememória, e também outras classificações considerando o nível de abstração (STRINGHINI etal., 2012)

17

Page 20: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

18

• Multiprocessadores: máquinas com memória compartilhada que possuem velocidadesde acesso uniforme e possibilitam o modelo de programação multithreaded.

• Single Instruction, Multiple Threads (SIMT): definição criada pela NVIDIAonde a computação SIMD é combinada com multitreading, cada thread em execuçãonos cores irão executar a mesma instrução como em um passo de execução.

2.2. Dispositivos AceleradoresEsta seção tem como principal objetivo demonstrar os principais dispositivos aceleradores,demonstrando semelhanças e diferenças em suas arquiteturas, será demonstrado FPGAs,Intel Xeon phi e GPUs. A seção 2.2.3 sobre GPU terá maior destaque pois é o dispositivoque será utilizada neste trabalho.

2.2.1. Arranjo de Portas Programáveis (FPGA)

Arranjos Programáveis são atualmente a base da área de computação reconfigurável, sãodispositivos que permitem programar/reconfigurar o hardware do elemento de processamentoconforme a necessidade (BRODTKORB et al., 2010).

O primeiro dispositivo Arranjo de Portas Programáveis (FPGA) foi desenvolvidopelo co-fundador da empresa Xilinx Ross Freeman em 1984. Inicialmente foi desenvolvidopara ser usado em lógica discreta, porém foi expandido para áreas como processamento desinais, e recentemente para ser usado como dispositivo acelerador para computação de altaperformance (BRODTKORB et al., 2010).

Seu funcionamento consiste em um conjunto de blocos que podem ser configuráveis,bem como blocos de processamento de sinais digitais e opcionalmente conectados por umainterconexão flexível com cores CPUs. Quando configuradas, as FPGAs funcionam com oscircuitos integrados feitos para aplicações específicas (BRODTKORB et al., 2010). A Figura2.1 apresenta um esquema genérico de um sistema heterogêneo entre uma CPU e de umFPGA.

O grande diferencial de um FPGA para um CPU é a capacidade de configurarmos seuhardware para desempenhar qualquer combinação de funções digitais que se deseja. Tambémpode-se implementar algoritmos de forma paralela, o que significa que pode-se processar umaenorme quantidade de dados de forma rápida e eficiente.

2.2.2. Intel Xeon Phi

A Intel começou o desenvolvimento da tecnologia em 2004 quando as equipes de arquitetosde processadores começaram a procurar uma solução para reduzir o consumo de energia dafamília Intel Xeon que foi desenvolvida em 2001 (RAHMAN, 2013).

Page 21: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

19

Figura 2.1. Sistema heterogêneo CPU e FPGA. Fonte: (BRODTKORB et al., 2010)

Em primeiro momento as equipes de projeto se concentraram em núcleos Pentium 5conectados através de uma interface de anel, adicionado a este formato unidades de funçãofixa. O objetivo do projeto era criar uma arquitetura que equilibrasse o multiprocessamentoem nível de chip com threads e paralelismo em nível de dados.

Intel Xeon Phi é composto por até 61 núcleos de arquitetura Intel. Para que hajauma comunicação entre tantos núcleos as interconexões são projetadas para manter o tráfegode memória/dados entre os núcleos e várias partes do chip. Na Figura 2.2 é demonstrado umlayout lógico do co-processador Intel Xeon Phi, sendo separado em oito controladores dememória representados como "8x MC distribuídos", L2 cache totalmente coerentes entre si,essa coerência é feita através dos tag directories que são utilizados para procurar os dados decache distribuídos entre os núcleos. Cada núcleo é capaz de executar operações vetoriais de512 bits por ciclo e pode hospedar até 16 GB de memória de largura de banda.

Para atingir um bom desempenho e eficiência energética, o código deve ter certascaracterísticas:

• O fragmento do código que está sendo executado no coprocessador tem de ser altamenteparalelo e deve ser escalável com o número de núcleos, resumindo, o fragmento docódigo deve ser capaz de utilizar todos os núcleos disponíveis sem mantê-los ociosos.

• Deve ser passível de transformações para utilizar instruções vetoriais.• O código deve ser capaz de ocultar a latência de comunicação de Entrada/Saída com

o host. Isso é necessário porque o processador do host será o elemento principal deprocessamento, sendo responsável pela maioria dos dados de entrada e saída para oarmazenamento de dados permanente e para gerenciar o tráfego de rede para outrosnós em um cluster ou grade.

Atualmente o Intel Xeon Phi está sendo utilizado para aplicações de computaçãoem áreas como, previsão do tempo, ciências médicas, exploração de energia, serviços financeirose pesquisa acadêmica. Se tais aplicações citadas forem consideradas adequadas para a

Page 22: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

20

Figura 2.2. Layout lógico do coprocessador Intel Xeon Phi. Fonte: (RAHMAN, 2013)

arquitetura Xeon Phi e se estiverem programadas adequadamente, o Xeon Phi possibilitaum desempenho e uma eficiência de energia muito maior do que o atingível somente pelosnós do host (RAHMAN, 2013).

2.2.3. Unidades de Processamento Gráfico (GPU)

GPUs são dispositivos aceleradores que atuam em conjunto com as CPUs, atualmente asduas principais fabricantes de GPUs são a NVIDIA e AMD (STRINGHINI et al., 2012). Aprimeira GPU foi criada em 1999 pela NVIDIA e denominada GeForce 256, possuía somenteum processador gráfico de tempo real, também um vértice de ponto flutuante de 32 bitsconfiguráveis e programáveis com APIs OpenGL e Microsoft DirectX (NICKOLLS; DALLY,2010).

Em 2006 a NVIDIA lançava a primeira arquitetura GPU programável em C com oCUDA, chamada de GeForce 8800. Seu hardware executava eficientemente 12,228 threadsconcorrentes em 128 cores. A GeForce 8800 foi a primeira GPU a usar threads escalares aoinvés de processadores vetoriais, combinando linguagens escalares padrão com C e eliminandoa necessidade de gerenciar registros e operações vetoriais. Foram adicionadas instruçõespara suportar C e outras linguagens de uso geral, incluindo aritmética de números inteiros,aritmética de ponto flutuante (IEEE 754) e instruções de acesso load/store com endereçamentode bytes (NICKOLLS; DALLY, 2010).

O funcionamento de uma GPU é feita por centenas de núcleos (cores) que executamum determinado código através de centenas de threads concorrentes (STRINGHINI et al.,

Page 23: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

21

2012). Para abordar diferentes segmentos de mercado, a NVIDIA separou as GPUs em váriasarquiteturas (Kepler, Fermi e Pascal), estas arquiteturas possuem diferenças, no número demultiprocessadores de fluxo para escalar o desempenho da computação, número de memóriaspara dimensionar a largura de banda e a capacidade da memória (NICKOLLS; DALLY, 2010).Nas próximas seções serão abordadas as diferenças entre as arquiteturas Fermi, Kepler ePascal.

Arquitetura Fermi

A primeira GPU baseada em Fermi foi implementada com 3 bilhões de transistores, com 512núcleos CUDA. Um núcleo CUDA executa uma instrução inteiro ou ponto-flutuante para cadathread em um ciclo de clock. Os 512 núcleos CUDA são organizados em 16 multiprocessorSM de 32 núcleos cada. A GPU tem seis partições de memória de 64 bits, para uma interfacede memória de 384 bits, suportando no total 6 Giga bytes de memória. A conexão entre aGPU com a CPU é feita via barramento PCI-Express (NVIDIA, 2009).

Na Figura 2.3 é demonstrado a divisão dos 16 SM, representadas pela tira retangularvertical que contém uma parte laranja (scheduler e dispath), porção verde (unidades deexecução) e porções azuis claro que são arquivo de registro e cache L1.

Figura 2.3. Modelo da arquitetura Fermi. Fonte: (NVIDIA, 2009)

Page 24: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

22

Cada SM possui 32 cores CUDA, sendo que, cada processador CUDA possui umaunidade lógica aritmética (ALU) completamente pipeline e uma unidade de ponto flutuante(FPU) implementado sobre os padrões IEEE 754-2008 (NVIDIA, 2009).

Figura 2.4. Fermi Streaming Multiprocessor (SM). Fonte: (NVIDIA, 2009)

Na Figura 2.4 é apresentado como é a divisão de cada SM, sendo que, cada CUDAcore implementa uma unidade lógica aritmética inteira e de ponto flutuante, e para cada SMsão escalonados dois grupos de 32 threads paralelos chamados warps, 4 grupos de UnidadesFuncionais Especiais (SFU) que são para instruções especiais (seno, cosseno e raiz quadrada)e 16 unidades de load/store.

Arquitetura Kepler

Projetado para ser uma potência de processamento paralelo junto com economia de energia,a arquitetura Kepler conta com 7, 1 bilhões de transístores e taxa de 1 Tera Flop de duplaprecisão com uma eficiência de 80% superior a arquitetura Fermi e 3× maior o poder dedesempenho por watt (NVIDIA, 2012).

Também foram adicionados recursos como paralelismo dinâmico, desta forma,adiciona a capacidade para a GPU sincronizar os resultados e controlar o agendamento

Page 25: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

23

de novos trabalhos sem envolver a CPU, permitindo que um kernel possa fazer chamadas aoutros kernels. Hyper-Q que permite vários núcleos de CPU lancem trabalho em uma únicaGPU simultaneamente, aumentando a utilização da GPU e reduzindo o tempo de inatividadeda CPU. Outra funcionalidade adicionada foi a unidade de gerenciamento de grids, estegerencia e prioriza os grids a serem executados na GPU e por fim a funcionalidade GPUDirectque permite que GPUs em um único computador ou em diferentes servidores possam trocardados diretamente sem precisar envolver a CPU.

Na Figura 2.5 mostra a arquitetura Kepler completa dividida entre os 15 SM com192 núcleos cada.

Figura 2.5. Diagrama completo arquitetura Kepler. Fonte: (NVIDIA, 2012)

Cada uma das unidades de multiprocessadores da arquitetura Kepler SM possui 192núcleos CUDA (Figura 2.6) de precisão única, e cada núcleo possui unidades lógica aritméticade inteiros e ponto-flutuante. A arquitetura mantém a aritmética de precisão simples e duplado padrão IEEE 754-2008 e incluindo a operação de multiplicação de fusíveis (FMA).

Para aumentar significativamente o desempenho de dupla precisão da GPU foimantido as SFU porém com um acréscimo de 8x o número de SFU comparado com aarquitetura Fermi (NVIDIA, 2012).

Page 26: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

24

Figura 2.6. Kepler Streaming Multiprocessor (SM). Fonte: (NVIDIA, 2012)

Arquitetura Pascal

Construído para ser o processador de computação paralela para atender as necessidadesdos mercados de computação de alto desempenho. A arquitetura Pascal é composto deuma matriz de Graphics Processing Clusters (GPC), Texture Processing Clusters (TPC),multiprocessadores SM e controladores de memória. Uma placa de vídeo completa suportaseis GPCs, 60 Pascal SMs, 30 TPCs e oito controladores de memória de 512 bits (4096 nototal) (NVIDIA, 2016).

Cada GPC tem dez SMs. Cada SM tem 64 núcleos CUDA e quatro unidades detextura. Com 60 SMs tem um total de 3840 CUDA cores e 240 unidades de textura. Cadacontrolador de memória está ligado a 512 kilobytes de cache L2, e cada pilha é controladapor um par de controladores de memória. A GPU completa inclui um total de 4096 kilobytesde cache L2 (NVIDIA, 2016).

Page 27: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

25

A Figura 2.7 mostra uma GPU completa com 60 unidades SM.

Figura 2.7. Arquitetura Pascal completa com 60 unidades SM. Fonte: (NVIDIA, 2016)

O SM da arquitetura Pascal incorpora 64 núcleos CUDA de precisão única, divididoem dois blocos de processamento, cada um com 32 núcleos CUDA de precisão única, um bufferde instrução, um warp scheduler e duas unidades dispatch. Comparando com a arquiteturaKepler, a arquitetura Pascal possui o mesmo número de registros, porém a nova arquiteturapossui muito mais SM, significa que os threads em toda a GPU tem acesso a mais registros, esuporta mais threads, warps e blocos por threads.

Outra comparação com arquitetura Kepler é que o SM de Pascal possui umaorganização de dados mais simples e requer menos área de matriz e menos energia paragerenciar transferências de dados dentro do SM. O Pascal também fornece instruções deload/store sobrepostas para aumentar a utilização de pontos flutuantes, proporcionando maiordesempenho e consumo de energia, cada warp scheduler é capaz de despachar duas instruçõesde warp por ciclo de clock.

2.3. Modelo de Programação (CUDA)CUDA é a tecnologia da NVIDIA introduzida em 2006 conhecida como Arquitetura deComputação Paralela de Propósito Geral (STRINGHINI et al., 2012). Usando CUDAvocê pode acessar a GPU para resolver problemas computacionais complexos de uma formaeficiente (CHENG et al., 2014).

Page 28: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

26

Figura 2.8. Pascal unidade SM. Fonte: (NVIDIA, 2016)

A plataforma CUDA é acessível através das diretrizes de compilação, interfaces deprogramação e extensões para linguagens de programação padrão da indústria (CHENG etal., 2014), incluindo C, C++, Fortran e Python.

Para realizar códigos paralelos, desenvolvedores devem ter um conhecimento aosrecursos arquiteturais da GPU e conhecimento básico de CPU, principalmente o conceito delocalidade. Existem dois tipos básicos de localidade. Localidade temporal que refere-sea reutilização de dados e recursos dentro de períodos de tempo relativamente pequeno, elocalidade espacial que refere-se ao uso de elementos de dados em locais de armazenamentorelativamente próximos (CHENG et al., 2014).

Outro conhecimento que o desenvolvedor deve ter sobre códigos paralelos são de hostque é a CPU e sua memória e device que é a GPU e sua memória, contudo, o componenteprincipal do modelo de programação CUDA é o kernel.

O kernel é o código que deve ser executado no dispositivo GPU. Quando um kernelé lançado o controle é retornado imediatamente para o host liberando a CPU para executartarefas adicionais complementadas pelo código paralelo executado no dispositivo. Na Figura2.9, o código serial é executado no host, enquanto o código paralelo é executado no dispositivoGPU (CHENG et al., 2014). Um fluxo de processamento de um programa CUDA segue o

Page 29: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

27

padrão:

1. Copie os dados da memória CPU para a memória da GPU;2. Realiza as chamadas do kernels para operar sobre os dados armazenados na memória

da GPU;3. Copie dados de volta da memória GPU para a memória da CPU.

Figura 2.9. Fluxo de execução de um código em CUDA. Fonte: (CHENG et al., 2014)

Quando uma função kernel é iniciada do lado do host, a execução é movida paraum dispositivo onde um grande número de threads é gerado e cada segmento executa asinstruções especificadas pela função do kernel (CHENG et al., 2014). CUDA expõe umaabstração de hierarquia de thread demonstrado na Figura 2.10, decomposta em blocos dethreads e grids de blocos.

Todas as threads gerados por um único lançamento do kernel são coletivamentechamados de grid. Todos os segmentos em um grid compartilham o mesmo espaço de memóriaglobal e é composto de muitos blocos de threads. Um bloco de thread é um grupo de threadsque podem cooperar entre si por meio de memória compartilhada local e sincronização local(CHENG et al., 2014).

Page 30: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

28

Figura 2.10. Divisão hierárquica de grids, blocos e threads. Fonte: (CHENG et al., 2014)

Vale ressaltar que os threads de blocos diferentes não podem cooperar e cada segmentode thread depende das coordenadas blockIdx (índice do bloco dentro de uma grid) ethreadIdx (índice de threads dentro de um bloco) para distinguirem uma das outras (CHENGet al., 2014). Esses valores são disponibilizados em variáveis embutidas e podem ser acessadosdentro do código do kernel para o cálculo do 𝑖𝑑 global de cada uma das threads criadas como lançamento da execução do kernel.

CUDA permite definir um arranjo de threads formado por um grid de blocos, em atétrês dimensões, e cada bloco também pode ter até três dimensões. Desta forma, problemascom domínios de dimensões variadas pode ser solucionados com um mapeamento em um gridde blocos de threads, tal como uma matriz ou uma imagem bidimensional (STRINGHINIet al., 2012). Uma configuração de 𝑔𝑟𝑖𝑑(𝑔𝑥, 𝑔𝑦, 𝑔𝑧) e 𝑏𝑙𝑜𝑐𝑜(𝑏𝑥, 𝑏𝑦, 𝑏𝑧) cria a estrutura doarranjo de threads. A Figura 2.11 apresenta a correspondência da estrutura criada na visãológica (software) e o seu mapeamento para o hardware.

A Figura 2.12 apresenta como os blocos são atribuídos para os multiprocessadores esuas threads são organizadas em warps que são escalonados e as threads pertencentes a umwarp (lanes) serão executadas por cada core.

Por exemplo, em uma soma de vetores temos que dois arranjos A e B de tamanho𝑁 tem seus elementos somados um a um e consequentemente o resultado da adição éarmazenado em um vetor resultante, aqui denominado C. O Código 2.1 apresenta como asoma de dois vetores pode ser feita na linguagem C.

Page 31: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

29

Figura 2.11. Mapeamento da visão lógica para o hardware

Figura 2.12. Organização do arranjo de threads

� �1 int N = 1024 ;2 int sumvector ( f loat ∗ A, f loat ∗ B, f loat ∗ C) {3 int i ;4 for ( i =0; i<N; i++){5 C[ i ] = A[ i ] + B[ i ] ;6 }7 }� �

Código 2.1. Exemplo de soma de vetores na linguagem C

Contudo, para o desenvolvimento do código em CUDA a função sumvector deve sermodificada para se transformar em um kernel. Como há paralelismo entre as iterações dolaço, pode-se escrever uma versão para CUDA substituindo as 𝑁 iterações por um arranjode threads no qual cada thread executaria o código equivalente a uma das iterações do laço

Page 32: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

30

original.No intuito de demonstrar a complexidade da definição do arranjo de threads os

Códigos 2.2, 2.3 e 2.4 apresentam variações de algums definições possíveis. Existem diversasmaneiras de se especificar o arranjo de threads que irão executar o código do kernel. OCódigo 2.2 apresenta a possibilidade de executar o kernel criando um grid com 𝑁 blocos com1 thread cada (linha 10). A extensão que CUDA faz da linguagem C modifica a chamadade funções para que a ativação de uma função kernel seja distinta da chamada de umafunção comum, a chamada 𝑉 𝑒𝑐𝐴𝑑𝑑 <<< 𝑁, 1 >>> (𝑑_𝐴, 𝑑_𝐵, 𝑑_𝐶, 𝑁) traz a definiçãodas dimensões do grid e do bloco de threads entre <<< e >>> que antecedem os parâmetrosda função kernel.� �1 __global__ void VecAdd( f loat ∗ A, f loat ∗ B, f loat ∗ C, int N) {2 int id = blockIdx . x ;3 i f ( id < N)4 C[ id ] = A[ id ] + B[ id ] ;5 }6

7 int main ( ) {8 /∗ Declaracao e t r a n s f e r e n c i a s de dados foram supr imidas . ∗/9 int N = 1024 ;

10 VecAdd<<<N, 1>>>(d_A, d_B, d_C, N) ;11

12 return 0 ;13 }� �Código 2.2. Exemplo de soma de vetores em CUDA utilizando 𝑁 blocos com 1 thread cada

No Código 2.3 apresenta uma outra versão, a possibilidade de se criar um grid comum único bloco de 𝑁 threads.� �1 __global__ void VecAdd( f loat ∗ A, f loat ∗ B, f loat ∗ C, int N) {2 int id = threadIdx . x ;3 i f ( id < N)4 C[ id ] = A[ id ] + B[ id ] ;5 }6

7 int main ( ) {8 /∗ Declaracao e t r a n s f e r e n c i a s de dados foram supr imidas . ∗/9 VecAdd<<<1, N>>>(d_A, d_B, d_C, N) ;

10

11 return 0 ;12 }� �

Código 2.3. Exemplo de soma de vetores em CUDA utilizando 1 bloco com 𝑁 threads

Page 33: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

31

O Código 2.4 apresenta uma combinação do uso de blocos e threads, o que possibilitauma definição de arranjos de threads mais elaborados, o que é útil para problemas comestruturas de domínio mais complexas.� �1 __global__ void VecAdd( f loat ∗ A, f loat ∗ B, f loat ∗ C, int N)2 {3 int id = blockDim . x ∗ blockIdx . x + threadIdx . x ;4 i f ( id < N)5 C[ id ] = A[ id ] + B[ id ] ;6 }7

8 int main ( ) {9 /∗ Declaracao e t r a n s f e r e n c i a s de dados foram supr imidas . ∗/

10

11 int threadsPerBlock = 256 ;12 int blocksPerGrid = (N + threadsPerBlock − 1) / threadsPerBlock ;13 VecAdd<<<blocksPerGrid , threadsPerBlock >>>(d_A, d_B, d_C, N) ;14

15 return 0 ;16 }� �Código 2.4. Exemplo de soma de vetores em CUDA com um arranjo de threads definindo-seum grid de blocos de threads

Embora foi utilizado nos exemplos definições únicas para as dimensões de grids eblocos, essas dimensões podem ser declaradas com o tipo dim3 possibilitando definições dearranjos mais complexos. O Código 2.5 apresenta uma declaração de um grid utilizando asdimensões 𝑥 e 𝑦 com o valor 32 e um bloco utilizando a dimensão 𝑥 também com o valor 32.Esta definição irá criar um 𝑔𝑟𝑖𝑑 de 32× 32 = 1024 blocos e cada bloco terá 32 𝑡ℎ𝑟𝑒𝑎𝑑𝑠, o quepermitiria no nosso exemplo de soma de vetores o cálculo para vetores de 32768 elementos.� �1 int main ( ) {2 /∗ Declaracao e t r a n s f e r e n c i a s de dados foram supr imidas . ∗/3

4 dim3 g r id (32 ,32 ,1 ) ;5 dim3 bloco (32 , 1 , 1 ) ;6 VecAdd<<<grid , bloco >>>(d_A, d_B, d_C, N) ;7

8 return 0 ;9 }� �Código 2.5. Exemplo de soma de vetores em CUDA com um arranjo de threads definindo-seum grid de blocos de threads

O cálculo do 𝑖𝑑 global de cada thread depende das dimensões para grid e blocosutilizada. Nos Códigos 2.2, 2.3 e 2.4 é visto que existem diversas maneiras de se definir o

Page 34: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

32

arranjo de threads que executarão o código da função kernel e o 𝑖𝑑 global da thread deve sercalculado conforme a estrutura do arranjo de threads declarado.

O cálculo do 𝑖𝑑 pode ser extraído para funções que serão ativadas conforme a definiçãodo 𝑔𝑟𝑖𝑑 e dos blocos. No Código 2.6 são apresentadas funções para o cálculo do 𝑖𝑑 dasthreads quando são utilizadas apenas uma das dimensões (1D_1D), uma versão para gridsque utilizem duas dimensões e blocos com uma dimensão (2D_1D) e a versão mais genéricapara quando as 6 dimensões são utilizadas (3D_3D).� �1 __device__ int getGlobalIdx_1D_1D ( ) {2 int threadId = blockIdx . x ∗ blockDim . x + threadIdx . x ;3 return threadId ;4 }5 . . .6 __device__ int getGlobalIdx_2D_1D ( ) {7 int blockId = blockIdx . y ∗ gridDim . x + blockIdx . x ;8 int threadId = blockId ∗ blockDim . x + threadIdx . x ;9 return threadId ;

10 }11 . . .12 __device__ int getGlobalIdx_3D_3D ( ) {13 int blockId = blockIdx . x + blockIdx . y ∗ gridDim . x + gridDim . x14 ∗ gridDim . y ∗ blockIdx . z ;15 int threadId = blockId ∗ ( blockDim . x ∗ blockDim . y ∗ blockDim . z )16 + ( threadIdx . z ∗ ( blockDim . x ∗ blockDim . y ) )17 + ( threadIdx . y ∗ blockDim . x ) + threadIdx . x ;18 return threadId ;19 }� �

Código 2.6. Exemplo da linearização das dimensões em um 𝑖𝑑 único

Assim, para um grid de blocos de threads a linearização do 𝑖𝑑 global de cadauma das threads pode ser calculada com operações de multiplicação e adição utilizando asvariáveis embutidas (blockIdx.x, blockDim.[x,y], threadIdx.[x,y,z]). O Código 2.7 demonstra aimplementação do kernel em CUDA.� �1 __global__ void vecAdd ( f loat ∗A, f loat ∗B, f loat ∗C, int N, int funcId ) {2 int id = getGlobalIdFunc [ funcId ] ( ) ;3 i f ( id < N)4 C[ id ] = A[ id ] + B[ id ] ;5 }� �

Código 2.7. Exemplo do kernel para a soma de vetor

A verificação se o 𝑖𝑑 da thread é menor que o número de elementos na estrutura dedados é necessária para que apenas threads no domínio sejam executadas. Então, da mesma

Page 35: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

33

forma com as dimensões separadas, é criado o kernel que fará a execução em paralelo. Norepositório do GitHub1 é apresentado o código completo do exemplo soma de vetores emCUDA.

Quando os kernels são gerados é necessário que haja uma compilação do código dokernel escrito na linguagem C para a representação de código intermediário das GPUs daNVIDIA que é denominado de Parallel Thread Execution – PTX (NVIDIA, 2014). Onvcc é um compilador para código C/C++ com suporte a CUDA que fornece opções de linhade comando simples semelhantes a compiladores como o GCC. Seu fluxo de trabalho consisteem separar o código que será executado do lado host e o código do kernel que executarána GPU. Normalmente, para o código do lado host utiliza o compilador padrão do sistemae gera o código para dispositivo em um formato de montagem intermediário chamado dePTX (NVIDIA, 2014).

A partir do código PTX o código binário final para o conjunto de instruções daarquitetura do dispositivo é gerado e pode ser executado. Contudo, a escrita do código emCUDA e sua execução em GPU não fornece análise de desempenho do programa, e podeser que código desenvolvido não esteja utilizando todos os recursos e como consequêncianão atinja um desempenho satisfatório na arquitetura em questão (CHENG et al., 2014).Para esta análise, há uma ferramenta de perfilamento integrada com CUDA que é utilizadapara analisar o desempenho do programa, esta ferramenta é chamada de NVIDIA Profiler– nvprof (CHENG et al., 2014).

O nvprof foi introduzido na versão 5 do CUDA e tem a função de exibir informaçõesdetalhadas na linha de comando. Ele permite a coleta da linha do tempo de atividadesrelacionadas ao CUDA tanto na CPU quanto na GPU, incluindo a execução do kernel,transferências de memória, coletando contadores do hardware, eventos e métricas dedesempenho para os kernels CUDA (CHENG et al., 2014).

Para identificar gargalos de desempenho em um kernel, é importante escolher métricasde desempenho apropriadas e realizar comparações, sendo que há três limitadores para odesempenho de um kernel. Estes limitadores são a largura de banda da memória (métricagld_efficiency), utilização dos recursos (métrica achieved_occupancy), número deinstruções executadas (métrica inst_executed) e latência de memória (sm_efficiency)(CHENG et al., 2014).

A utilização do nvprof com estas métricas é importante para a programação deCUDA pelas seguintes razões (CHENG et al., 2014):

• Uma implementação de kernel simples geralmente não produz o melhor desempenho.As métricas pode ajudar a encontrar regiões críticas de código que são gargalos dedesempenho.

1 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/blob/master/benchmarks/sumvector/src/sumvector.cu>

Page 36: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

34

• CUDA particiona os recursos de computação em SM com vários blocos de threads. Esseparticionamento faz com que alguns recursos se tornem limitadores de desempenho,com as métricas pode-se obter informações sobre como os recursos de computação estãosendo utilizados.

• CUDA fornece uma abstração da arquitetura de hardware que permite controlar aconcorrência entre threads. As métricas podem ajudar a medir, visualizar e orientar asotimizações, pois fornecem uma visão profunda do desempenho do kernel e ajuda aidentificar estrangulamentos nos kernels.

2.4. AutotuningAutotuning é uma técnica de otimização de software concebida a partir de bibliotecasnuméricas sequenciais, em especial da biblioteca Automatically Tunned Linear AlgebraSoftware (ATLAS). Whaley e Dongarra (1999) utilizaram o conceito de auto-tunner, poisperceberam que percorrer todo o espaço de busca para a geração automática e otimização deuma hierarquia de memória não seria uma tarefa simples e rápida, então proporam a idéia deuma aplicação que realizasse essa busca de maneira automatizada.

Assim Williams (2008) propôs em sua tese o conceito de auto-tunner que tem a tarefade buscar, dentro de um espaço de possibilidades, a implementação de uma rotina kernelque apresente o melhor desempenho para uma determinada arquitetura. Segundo Williams(2008), um autotuning deve ser criado a partir de três conceitos principais, espaço de soluções,geração de código e exploração do espaço de otimização, este conceito foi implementado naferramenta OpenTuner.

O espaço de soluções refere-se a explorar o melhor desempenho do kernel. Estaexploração utiliza o conjunto de parâmetros que o kernel necessita para realizar esta busca,estes parâmetros podem ser estruturas de dados alternativos para o algoritmo, eliminação dedesvios condicionais e otimizações de laços.

A partir dos parâmetros determinados pelo espaço de otimização, o auto-tunner geramutações de kernel em uma linguagem de alto nível. A escolha de qual mutação apresenta omelhor desempenho utilizando a exploração do espaço de otimização.

A exploração do espaço de otimização pode ser feita a partir de três abordagens. Aprimeira é através da busca exaustiva, a qual o kernel passa por todas as possibilidadesque a arquitetura oferece, nesta abordagem o espaço de busca pode-se tornar inviável emtermos de tempo. A segunda abordagem é o uso de heurísticas baseadas na arquitetura, estasheurísticas pode ser o intervalo de valores que uma arquitetura delimita, assim o autotuningtrabalha somente dentro deste espaço. Uma terceira técnica que é utilização de algoritmos debusca, desta forma, o auto-tuner efetua uma busca linear dentro de todo o espaço de buscade um determinado parâmetro.

Page 37: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

35

Na ferramenta OpenTuner que será apresentado na Seção 2.4.1 utilizou três tiposde algoritmos de busca, bem como implementou a ferramenta utilizando os conceitosapresentados.

2.4.1. OpenTunerOpenTuner é uma ferramenta de código aberto que tem como objetivo a fácil construçãode programa auto-tuner para um domínio específico (ANSEL et al., 2014). Apresenta umaconfiguração extensível e representação técnica capaz de suportar tipos de dados complexos edefinidos pelo usuário e heurísticas de pesquisa personalizadas.

Seu conceito central é encontrar o melhor desempenho para que a aplicação necessitacom o menor tempo de trabalho, para isso, utiliza técnicas de busca que intercalam entresi , sendo que as técnicas que retornam valores abaixo do esperado são descartados do quetécnicas que encontraram valores esperados. Na Figura 2.13 mostra como o OpenTuner realizao processo de autotuning.

Figura 2.13. Funcionamento do OpenTuner. Fonte: (ANSEL et al., 2014)

Primeiro deve ser especificado o espaço de busca, este espaço inclui um conjuntode parâmetros que o OpenTuner pesquisara para realizar os testes. Segundo, o usuáriodeve implementar o programa autotuning que realizará os testes no conjunto de parâmetrosutilizando as técnicas de busca (o funcionamento das técnicas é demonstrado na Figura 2.14),esta implementação do usuário deve ser realizado na linguagem de programação Python e devehaver o método configuration especificado pela Interface de Programação de Aplicativos (API)do OpenTuner que realizará as escolhas dos parâmetros, este método retorna os parâmetros(measurement) que será utilizado no método run que será executado e após o término daexecução retornará as medidas de tempo, métricas ou consumo energético confome definiçãodo usuário.

Na execução do método de configuration é realizado a escolha da técnica de buscaque será executado naquele momento, sendo que na primeira execução todos os algoritmosde busca realizam a execução e é retornado uma taxa utilizável para comparar com os outrosalgoritmos. Assim que realizado a primeira execução todos os algoritmos estão com uma taxa

Page 38: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

36

Figura 2.14. Modelo de divisão de trabalho das técnicas de busca. Fonte: (ANSEL et al., 2014)

armazenada e compartilhada no ResultsDB, a partir destas taxas o algoritmo AUC Banditencapsula um trade-off fundamental chamado exploitation (uso da técnica mais conhecida) eexploitation (estimativa de desempenho de todas as técnicas) e realiza novamente os testescom os algoritmos. A partir de várias execuções o AUC bandit terá um conjunto de resultadosentre as técnicas que tiveram um valor satisfatório (estes serão ativados novamente) e comtécnicas que não tiveram um valor satisfatório (não são executados novamente).

A ferramenta OpenTuner utiliza de três algoritmos de busca Differential Evolution,Particle Swarm Optimization e Torczon Hill Climber de um algoritmo de moderaçãodenominado AUC Bandit.

• Differential Evolution: é um método de busca direta e paralelo que utiliza vetoresde parâmetros NP D-dimensionais com uma população G.A população inicial é escolhida aleatoriamente e deve tentar cobrir o espaço do parâmetrouniformemente, basicamente, o Differential Evolution gera novos vetores de parâmetrosadicionados a diferença ponderada entre dois vetores populacionais a um terceiro vetor.Se o vetor resultante produz um valor de função objetivo inferior ao de um elementoda população predeterminado, desta forma o vetor novo substitui o vetor com o qualfoi comparado, caso contrário o vetor antigo é armazenado (STORN; PRICE, 1997).Na Figura 2.15 mostra em duas dimensões os diferentes vetores gerados para a busca,sendo que, o primeiro vetor é demonstrado pela "onda"de maior tamanho e o mínimo éonde se encontra a solução ótima.

• Particle Swarm Optimization: Desenvolvido em 1995 por Kennedy e Eberhart o

Page 39: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

37

Figura 2.15. Processo de geração da função objetiva. Fonte: (STORN, 1996)

Particle Swarm Optmization pode ser entendido pela ideia de um enxame de abelhas.Imagine um enxame de abelhas em um campo, o objetivo é encontrar no campo alocalização com a maior densidade de flores sem qualquer conhecimento do campo apriori. Primeiro as abelhas começam em locais aleatórios com velocidades aleatóriasà procura de flores. Cada abelha pode recordar dos locais que encontrou a maioriadas flores, também sabe de algum modo os locais onde as outras abelhas encontraramuma abundância de flores. Dividida entre o retorno ao local onde pessoalmenteencontrara a maioria das flores, ou explorando a localização relatada por outras abelhas,alterando sempre sua trajetória de voar entre sua escolha e a escolha das outras abelhas,desta forma as abelhas exploram o campo, sempre sobrevoando aos locais onde temmaior concentração de flores, logo todas as abelhas enxameiam em torno deste ponto(KENNEDY; EBERHART, 1995).O funcionamento do algoritmo de busca consiste primeiro de uma partícula que temcomo princípio buscar a melhor localização pessoal bem como a melhor localizaçãogeral (local onde as outras abelhas foram), segundo a posição em que a "abelha"estálocalizada, por exemplo uma coordenada do plano 𝑥, 𝑦, terceiro uma função de aptidãoque retorna a densidade de flores, quanto maior a densidade melhor a localização.Também para compor o algoritmo há a função pbest que retorna a melhor localizaçãode flores para uma partícula e a função gbest que é a melhor localização de floressegundo todas as abelhas (ROBINSON; RAHMAT-SAMII, 2004).Na Figura 2.16 mostra que as partículas individuais (1 e 2) são aceleradas em direção alocalização da melhor solução gbest e a localização do seu próprio melhor pbest.

• Torczon Hill Climber : O algoritmo de busca Hill Climber é um algoritmo iterativoque começa através de uma possível solução, em seguida, tenta encontrar uma solução

Page 40: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

38

Figura 2.16. Funcionamento do algoritmo de busca Particle Swarm Optimization, em um espaçode busca 2D. Fonte: (ROBINSON; RAHMAT-SAMII, 2004)

melhor, alterando gradativamente um único elemento da solução. Se a mudança produzuma solução melhor, uma alteração incremental é feita para a nova solução, repetindoaté não encontre mais melhorias. Este algoritmo lembra a ideia de uma escalada a umamontanha (RUSSELL; NORVIG, 2003).Hill Climbing atinge soluções ótimas para problemas convexos, para outros casosapresenta somente máximos locais (pico que é maior do cada um dos seus estadosvizinhos, mas inferior ao máximo global), cumes que são uma sequência de máximoslocais que é muito difícil para algoritmos navegarem, e por planos, do qual não existesaída para cima, ou um cume a partir da qual o progresso é possível.Para conter esses problemas de busca, há algoritmos variantes do Hill Climbing comoStochastic Hill Climbing que escolhe aleatoriamente entre os movimentos ascedentes,a probabilidade da escolha do próximo passo varia com a inclinação do movimentode subida. Geralmente a convergencia deste algoritmo é mais lenta do que o HillClimbing, porém encontra soluções melhores. Também há o First-Choice Hill Climbingque primeiro implementa o Stochastic Hill Climbing, gerando sucessores aleatoriamenteaté que seja gerado um melhor que o estado atual. Esta estratégia é boa para casosonde há milhares de estados que podem ser sucessores (RUSSELL; NORVIG, 2003).Na Figura 2.17, demonstra o algoritmo de busca Hill Climbing em seu formato maisbásico. Em cada passo o nó atual é substituído pelo melhor vizinho, isso significa que ovizinho com o mais alto VALUE, este passo leva a possíveis máximos locais.

Page 41: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

39

Figura 2.17. Demonstração do Algoritmo de busca Hill Climbing. Fonte: (RUSSELL; NORVIG,2003)

2.5. Considerações FinaisNeste capítulo foram apresentados alguns conceitos e trabalhos relacionados com nossaproposta. Enfatizou-se principalmente a definição das dimensões do arranjo de threads para olançamento da execução de kernels que a plataforma CUDA deixa a critério do desenvolvedor,para que seja feita uma definição explícita conforme o domínio do problema. Grande partedas ferramentas de compilação apresentadas que geram código para GPU utilizam-se dedefinições genéricas para as dimensões (3D_3D) para garantir a cobertura no cálculo do𝑖𝑑 global das threads, mesmo para kernels que não utilizam todas as dimensões. O que nomínimo colocará mais instruções no código do kernel para esse cálculo.

Foi apresentado também o OpenTuner uma ferramenta para autotuning que pretende-se utilizar para a exploração do espaço de configurações das dimensões de grids e blocos embusca de padrões que possibilitem o melhor ajuste entre código e características do hardware.

Page 42: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Capítulo

3Estudo sobre Ajustes nas Dimensões de Kernels

No contexto de GPUs, existe uma relação entre a visão do modelo de programação que setem no software com o modelo de execução no hardware. No Capítulo 2 foi apresentadoo embasamento teórico levantado para o desenvolvimento deste trabalho. A Seção 2.2.3apresentou alguns conceitos sobre GPUs e a Seção 2.3 introduziu o desenvolvimento deaplicações paralelas para GPU utilizando CUDA.

Os recursos e capacidades do hardware determinam se os kernels de uma aplicaçãopodem ser lançados para a execução ou não. Uma das principais restrições é a quantidadetotal de memória que se tem disponível em cada dispositivo, pois as aplicações alocam dadosdurante sua execução e se a memória do dispositivo não for suficiente para alocar todos osdados necessários, tem-se um problema de capacidade de armazenamento que deverá serresolvido com alguma espécie de particionamento dos dados.

Outras restrições importantes são as dimensões máximas que são impostas pelomodelo da arquitetura para grids e blocos. Uma configuração de 𝑔𝑟𝑖𝑑(𝑥, 𝑦, 𝑧) e 𝑏𝑙𝑜𝑐𝑜(𝑥, 𝑦, 𝑧)cria a estrutura de um arranjo de threads. No caso específico de GPUs, a responsabilidade deespecificar as dimensões do arranjo de threads que deve ser criado, fica sobre o desenvolvedor.

Algumas abordagens tentam utilizar ferramentas de compilação que geram códigode maneira automática para GPU, entre elas estão o PoLLy (GROSSER et al., 2011, 2012), oKernelGen (MIKUSHIN et al., 2013, 2014) e o PPCG (VERDOOLAEGE et al., 2013). Essasferramentas geram código para um determinado alvo (CPU ou GPU), no caso de GPU muitasvezes é gerado um código genérico, utilizam dimensões genéricas para o arranjo de threads(grid, bloco, threads) que será criado, não se preocupam com o ajuste às característicasarquiteturais.

No contexto dessas ferramentas a preocupação está no fato de ser ou não ser possívelgerar uma versão de código que possa ser executado em paralelo. E então, uma versãoparalela é gerada com base na experiência dos desenvolvedores ou de maneira genérica sem a

40

Page 43: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

41

preocupação se este possui um ajuste melhor às características arquiteturais.Ajustar o código dos kernels para a arquitetura que está sendo utilizada é essencial

para se garantir uma utilização eficiente dos recursos disponíveis. Entretanto, não é umatarefa trivial, primeiro deve-se conhecer os componentes arquiteturais da GPU e ajustar ocódigo para que extraia o melhor desempenho possível.

Assim, o tema deste trabalho está relacionado com o ajuste de código com base nascaracterísticas arquiteturais. A busca no conjunto de configurações possíveis e válidas para oarranjo de threads, subdividido em grids, blocos e threads é guiada pelos resultados obtidos demétricas coletadas diretamente do hardware. O objetivo é escolher a melhor configuração quefavoreça ou propicie o melhor desempenho da GPU de maneira global ou em determinadoscomponentes, em específico.

3.1. Ajustes do lado do hardwareDesta forma, irá se verificar a escolha de uma determinada configuração ou a priorização deuma das dimensões influencia no desempenho. Uma vez que para diferentes configurações aspodem apresentar diferenças no desempenho.

No referencial teórico é visto que a execução de um kernel é necessário a definiçãodas dimensões de um arranjos de threads com grid(x,y,z) e bloco(x,y,z). Para realizara escolha de configurações, o desenvolvedor deve respeitar certas condições e restrições prédeterminadas pelo hardware para os grids e blocos, sendo elas:

1. O total de threads criadas em uma configuração será 𝑔𝑥× 𝑔𝑦 × 𝑔𝑧 × 𝑏𝑥× 𝑏𝑦 × 𝑏𝑧.2. A multiplicação das dimensões dos blocos não pode ultrapassar 512 ou 1024 dependendo

da arquitetura. Este valor é o número máximo de threads por blocos (𝑏𝑥×𝑏𝑦×𝑏𝑧 ≤ 1024).3. A multiplicação das dimensões do bloco (𝑏𝑥× 𝑏𝑦× 𝑏𝑧) tem que ser divisível por 32, pois

as threads são organizadas durante a execução em grupos de 32, em warps. Qualquerconfiguração que não seja múltipla de 32 apresentará o problema de divergência naexecução do kernel, no qual ficam lanes inativos dentro do warp, o que degrada odesempenho.

4. O total de threads criadas em uma configuração deve ser menor que o tamanho de 𝑁 ,esta condição se dá pelo fato que as threads não podem realizar trabalho com espaçosde memórias não alocados.

Para exemplificar o número de configurações válidas que pode haver para umdeterminado algoritmo, a Tabela 3.1 descreve o número de possibilidades que pode haverpara o algoritmo com um laço de 𝑁 iterações mapeadas em threads, como no exemplo somade vetores.

Ainda na Tabela 3.1 é possível ver que a escolha da melhor configuração se tornauma tarefa não trivial. Por exemplo, para o número de iterações igual a 64 pode-se haver

Page 44: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

42

Tabela 3.1. Configurações válidas para um determinado número de iterações

Tamanho do vetor Configurações Válidas64 63128 210256 486512 9461024 1656

... ...131072 13761262144 16481524288 194511048576 2267167108864 43799

as seguintes configurações de grids (na Tabela 3.2 apresentado por 𝑔𝑥,𝑔𝑦 e 𝑔𝑧) e blocos (naTabela 3.2 apresentado por 𝑏𝑥, 𝑏𝑦 e 𝑏𝑧).

Tabela 3.2. Configurações válidas para o número de iterações 𝑁 = 64

(𝑔𝑥,𝑔𝑦,𝑔𝑧)(𝑏𝑥,𝑏𝑦,𝑏𝑧)(1, 1, 2),(32, 1, 1)(1, 2, 1),(32, 1, 1)(2, 1, 1),(32, 1, 1)

...(1, 1, 2),(8, 4, 1)(1, 2, 1),(8, 4, 1)(2, 1, 1),(8, 4, 1)

...(1, 1, 2),(1, 1, 32)(1, 2, 1),(1, 1, 32)(2, 1, 1),(1, 1, 32)

A escolha da melhor configuração que se ajusta às características do hardware torna-se um problema. E para solucioná-lo é necessário testar todas as possíveis configuraçõesutilizando a técnica de força bruta ou alguma ferramenta que explore o espaço de configuraçõesutilizando técnicas de acelerem a busca e elimine testes desnecessários com configurações quenão melhoram o desempenho, ferramentas de autotuning.

Seja por força bruta, seja por autotuning, a escolha das melhores configurações se

Page 45: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

43

dará pela coleta de métricas de desempenho que a plataforma CUDA disponibiliza e podemser coletas com a ferramenta nvprof. Algumas dessas métricas são:

1. sm_efficiency: Porcentagem de tempo que uma warp está ativa em um multiprocessadorem relação a todos os multiprocessadores na GPU.

2. achieved_occupancy: Relação média entre warps ativos com o número máximo de warpssuportadas no multiprocessador.

3. inst_executed: Número de instruções executadas4. gld_efficiency: Relação do throughput carga de memória global solicitada para o

throughput de carga global requerido.

Queremos com os testes via ferramentas encontrar a melhor configuração ou padrõesde configurações que possibilitem o melhor ajuste do código de kernels nas dimensões ecaracterísticas dos dispositivos.

Com estas informações queremos verificar se é possível criar uma heurística comos padrões detectados pelas ferramentas de autotuning, que será utilizada para próximostrabalhos criar um passo para a ferramenta Low Level Virtual Machine (LLVM )-PoLLy. Aideia é que dado um código com laços aninhados, verificações se ele é paralelizável sejamfeitas e se for paralelizável ele terá seu código transformado em uma versão paralela e umkernel de código ajustado será gerado conforme o padrão detectado.

3.2. Ajustes do lado do softwareLaços de repetição são alvo de ferramentas que trabalham com o modelo polyhedral(BENABDERRAHMANE et al., 2010), pois em sua maioria códigos que possuem laçosapresentam algum paralelismo que em uma execução sequencial ficaria escondido. Laçosaninhados são um problema para desenvolvimento de códigos paralelos se apresentamdependências entre as iterações. Normalmente, as ferramentas aplicam transformaçõesmodificando o domínio de iterações formado pelas dimensões criadas com os índices doaninhamento.

Para que seja possível a criação de um kernel para GPU é necessário que o laço ouum conjunto de laços aninhados tenham iterações que possam ser executadas em paralelo,pois o modelo de execução das GPU trabalha com paralelismo de dados.

O Código 3.1 mostra um exemplo de um algoritmo que calcula uma tabela de senos ecossenos, note que o statement (S_1) que pertence ao corpo do laço mais interno é totalmentelivre de dependências pois não há acessos a elementos entre iterações. Dado um índice oselementos dos arranjos são acessados e o cálculo pode ser feito.

Page 46: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

44

� �1 for ( i = 0 ; i < nx ; ++i ) {2 for ( j = 0 ; j < ny ; ++j ) {3 for ( k = 0 ; k < nz ; ++k ) {4 i n d i c e = ( i ∗ ny ∗ nz ) + ( j ∗ nz ) + k ;5 xy [ i n d i c e ] = s i n ( x [ i n d i c e ] ) + cos ( y [ i n d i c e ] ) ; // S_16 }7 }8 }� �

Código 3.1. Exemplo de algoritmo que possui laços aninhados.

Além do ajuste nas dimensões de grids e blocos de threads que é do lado do hardware.O ajuste que queremos testar nos códigos dos benchmarks também trabalha sobre o software.O Código 3.1 pode ser transformado em

Dadas as dimensões que possibilitam a criação do arranjo de threads organizadoem um grid de blocos de threads e dado um código com laços aninhados. A ideia é migrariterações de laços para o arranjo de threads. O Código 3.2 apresenta parte do código deum benchmark com 3 laços aninhados, os testes que queremos realizar neste código é criaralgumas versões de kernels que executem o código original com 3 laços, outra que execute ocódigo com os 2 laços mais internos, outra que execute apenas o laço mais interno e finalmenteum kernel que execute apenas as instruções que estão no corpo do laço mais interno.� �1 __global__ void s incos_kernel_3 (DATA_TYPE∗ x , DATA_TYPE∗ y , DATA_TYPE∗ xy ,

int nx , int ny , int nz ) {2 int i , j , k , i n d i c e ;3 for ( i = 0 ; i < nx ; ++i ) {4 for ( j = 0 ; j < ny ; ++j ) {5 for ( k = 0 ; k < nz ; ++k ) {6 i n d i c e = ( i ∗ ny ∗ nz ) + ( j ∗ nz ) + k ;7 xy [ i n d i c e ] = s i n ( x [ i n d i c e ] ) + cos ( y [ i n d i c e ] ) ;8 }9 }

10 }11 }� �

Código 3.2. Código do kernel gerado com os 3 laços

O índice aqui é calculado pelos laços, uma cópia do kernel executando ostrês laços. E a ativação do kernel se dará pela chamada 𝑠𝑖𝑛𝑐𝑜𝑠_𝑘𝑒𝑟𝑛𝑒𝑙_3 <<

𝑑𝑖𝑚3(1, 1, 1), 𝑑𝑖𝑚3(1, 1, 1) >>> (...);� �1 __global__ void s incos_kernel_2 (DATA_TYPE∗ x , DATA_TYPE∗ y , DATA_TYPE∗ xy ,

int nx , int ny , int nz , int funcId ) {2 int i , j , k , i n d i c e ;

Page 47: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

45

3 i = getGlobalIdFunc [ funcId ] ( ) ;4 for ( j = 0 ; j < ny ; ++j ) {5 for ( k = 0 ; k < nz ; ++k ) {6 i n d i c e = ( i ∗ ny ∗ nz ) + ( j ∗ nz ) + k ;7 xy [ i n d i c e ] = s i n ( x [ i n d i c e ] ) + cos ( y [ i n d i c e ] ) ;8 }9 }

10 }� �Código 3.3. Código do kernel gerado com os 2 laços

As 𝑛𝑥 iterações são transferidas para as dimensões de grid e blocos de threads. Asiterações para 0 <= 𝑖 < 𝑛𝑥, o i é obtido com o id das threads.� �1 __global__ void s incos_kernel_1 (DATA_TYPE∗ x , DATA_TYPE∗ y , DATA_TYPE∗ xy ,

int nx , int ny , int nz , int funcId ) {2 int i , k , i n d i c e ;3 i = getGlobalIdFunc [ funcId ] ( ) ;4 for ( k = 0 ; k < nz ; k++) {5 i n d i c e = ( i ∗ nz ) + k ;6 xy [ i n d i c e ] = s i n ( x [ i n d i c e ] ) + cos ( y [ i n d i c e ] ) ;7 }8 }� �

Código 3.4. Código do kernel gerado com 1 laço

As (𝑛𝑥 * 𝑛𝑦) iterações dos laços são transferidas para o arranjos de threads. Cadathread irá executar o kernel com o código do laço mais interno, o que resulta em 𝑛𝑧 iteraçõese o índice é calculado como, 𝑖𝑛𝑑𝑖𝑐𝑒 = (𝑖 * 𝑛𝑧) + 𝑘.� �1 __global__ void s incos_kernel_0 (DATA_TYPE∗ x , DATA_TYPE∗ y , DATA_TYPE∗ xy ,

int nx , int ny , int nz , int funcId ) {2 int i n d i c e ;3 i n d i c e = getGlobalIdFunc [ funcId ] ( ) ;4 xy [ i n d i c e ] = s i n ( x [ i n d i c e ] ) + cos ( y [ i n d i c e ] ) ;5 }� �

Código 3.5. Código do kernel gerado sem os laços

Todas as (𝑛𝑥 * 𝑛𝑦 * 𝑛𝑧) iterações são transferidas para as dimensões do arranjo dethreads. O 𝑖𝑛𝑑𝑖𝑐𝑒 é calculado somente com base nas dimensões do arranjo de threads.

Outras transformações ou otimizações pode ser aplicadas, como a loop unroll(desenrolamento das iterações do laço) que na prática aumento o número de instruções nocorpo do laço ajustando o passo do laço (stride) que no exemplo está sendo incrementado em8.

Page 48: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

46

� �1 __global__ void s incos_kernel_1_unrol l_8 (DATA_TYPE∗ x , DATA_TYPE∗ y ,

DATA_TYPE∗ xy , int nx , int ny , int nz , int funcId ) {2 int i , k , i n d i c e ;3 i = getGlobalIdFunc [ funcId ] ( ) ;4 for ( k = 0 ; k < nz ; k+=8) {5 i n d i c e = ( i ∗ nz ) + k ;6 xy [ i n d i c e ] = s i n ( x [ i n d i c e ] ) + cos ( y [ i n d i c e ] ) ;7 xy [ i n d i c e + 1 ] = s i n ( x [ i n d i c e + 1 ] ) + cos ( y [ i n d i c e + 1 ] ) ;8 xy [ i n d i c e + 2 ] = s i n ( x [ i n d i c e + 2 ] ) + cos ( y [ i n d i c e + 2 ] ) ;9 xy [ i n d i c e + 3 ] = s i n ( x [ i n d i c e + 3 ] ) + cos ( y [ i n d i c e + 3 ] ) ;

10 xy [ i n d i c e + 4 ] = s i n ( x [ i n d i c e + 4 ] ) + cos ( y [ i n d i c e + 4 ] ) ;11 xy [ i n d i c e + 5 ] = s i n ( x [ i n d i c e + 5 ] ) + cos ( y [ i n d i c e + 5 ] ) ;12 xy [ i n d i c e + 6 ] = s i n ( x [ i n d i c e + 6 ] ) + cos ( y [ i n d i c e + 6 ] ) ;13 xy [ i n d i c e + 7 ] = s i n ( x [ i n d i c e + 7 ] ) + cos ( y [ i n d i c e + 7 ] ) ;14 }15 }� �

Código 3.6. Código do kernel gerado sem os laços

O objetivo com essas versões dos kernels é migrar iterações dos laços para a estruturado arranjo de threads. As versões de kernels são apresentadas na Tabela 3.3. Na primeiraversão sincos_kernel_3 todas as iterações são executadas por uma única thread que executauma cópia do kernel. Na versão sincos_kernel_2 as 𝑛𝑥 iterações do laço mais externo sãotransferidas para o arranjo de threads, o que resulta em 𝑛𝑥 threads executando cópias de umkernel formado com os dois laços mais internos.

Tabela 3.3. Versões de kernels

kernel Descrição

sincos_kernel_3 Os 3 laços do código original executados: 1configuração. O kernel que faz a execução dos 3 laçosaninhados é executado por uma única thread.

sincos_kernel_2 O kernel terá 2 laços do código original para executar.As 𝑛𝑥 iterações do laços mais externo do código originalforam transferidas para o arranjo de threads.

sincos_kernel_1 O kernel terá 1 laço do código original a ser executado.As (𝑛𝑥 * 𝑛𝑦) iterações dos dois laços mais externos foramtransferidas para o arranjo de threads.

sincos_kernel_0 Nenhum dos laços são executados. O kernel é formadosomente pelo corpo do laço mais interno do aninhamentooriginal. As (𝑛𝑥 * 𝑛𝑦 * 𝑛𝑧) iterações dos 3 laços aninhadosforam transferidas para o arranjo de threads.

Na versão sincos_kernel_1 teremos 𝑛𝑥×𝑛𝑦 iterações transferidas para o arranjo dethreads. E finalmente a versão sincos_kernel_0 tem-se 𝑛𝑥× 𝑛𝑦 × 𝑛𝑧 iterações transferidas

Page 49: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

47

para o arranjo, essas threads irão executar cópias do código que contém apenas as instruçõesdo corpo do laço mais interno.

A migração de iterações entre código do kernel e a estrutura do arranjo de threadspossibilita a busca de um equilíbrio entre as opções que executam menos threads com maiscomputação ou mais threads com menos computação. Possibilitando um ajuste no códigoconforme a disponibilidade de recursos da arquitetura. É interessante também para quese possa ajustar o código para garantir uma certa taxa de ocupação, questões de memóriacompartilhada e acessos à hierarquia de memória.

Quando há iterações de um ou mais laços para o arranjo de threads deve-se considerara computação inserida pelo cálculo do 𝑖𝑑 global de cada thread. Pois quanto mais dimensõesutilizadas, mais operações serão necessárias para o cálculo do 𝑖𝑑 global (linearização doendereço). Para exemplificar a quantidade de operações inseridas no kernel pelo cálculo do𝑖𝑑 global é apresentada na Tabela 3.4. O código que que apresenta todas as combinaçõespara o cálculo do id global da thread está no repositório do GitHub2

Tabela 3.4. Número de operações realizadas para o cálculo do 𝑖𝑑 global das threads

FunçãoOperações

Totaladd mult

getGlobalIdx_1D_1D() 1 1 2getGlobalIdx_1D_2D() 3 2 5getGlobalIdx_1D_3D() 6 3 9getGlobalIdx_2D_1D() 2 2 4getGlobalIdx_2D_2D() 4 3 7getGlobalIdx_2D_3D() 7 4 11getGlobalIdx_3D_1D() 4 3 7getGlobalIdx_3D_2D() 6 4 10getGlobalIdx_3D_3D() 9 5 14

3.3. Considerações FinaisNeste capítulo foram apresentados conceitos relacionados a ajustes do código pelo lado dohardware que é verificar a escolha de uma determinada configuração de grids e blocos oua priorização de uma das dimensões influencia no desempenho. Também foi apresentadoconceito do ajustes do lado do software que tem como objetivo criar kernels que consigamover um conjunto de laços aninhados para serem executadas em paralelo.

Nos capítulos seguintes serão apresentadas a metodologia empregada para realizaros experimentos, bem como os resultados que foram obtidos.2 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/blob/master/dimensions.h>

Page 50: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Capítulo

4Metodologia

Como metodologia para o desenvolvimento do trabalho, foram estipuladas algumas atividadese um conjunto de passos para a execução de experimentos com o benchmarks e a análisedos resultados obtidos para as métricas coletadas do hardware. Os passos definidos sãoapresentados na Figura 4.1.

Figura 4.1. Etapas para a realização da pesquisa

As seções 4.1, 4.2, 4.3 e 4.4 mostrarão mais detalhes sobre cada uma das etapas, res-pectivamente, a escolha dos benchmarks para a execução dos experimentos, o desenvolvimentodo código dos scripts para o OpenTuner, a execução dos testes e experimentos, a extraçãoda melhor configuração pela ferramenta OpenTuner e com base nas métricas coletadas dohardware e por fim as técnicas que foram aplicadas aos resultados dos experimentos natentativa de detectar padrões ou tendências nas configurações que pudessem influenciar nodesempenho.

48

Page 51: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

49

4.1. Uso dos benchmarksPara a realização de experimentos escolheu-se alguns benchmarks que atendessem ao critériode possuir código com dois ou mais dimensões de laços aninhados. Considerou-se na escolhaalgoritmos pertencentes aos conjuntos PolyBench (POUCHET et al., 2012), KernelGen(MIKUSHIN et al., 2014) e NVIDIA Cuda Samples (NVIDIA, 2009), que são benchmarkscom o objetivo de execução e monitoramento de kernels utilizados em dispositivos paralelos.Foram utilizadas as versões para GPU.

A escolha dos algoritmos dentro desse critério foi feita pois a ideia é testar atransferência ou migração de iterações dos laços para o arranjo de threads. Analisandoe ajustando a relação do número de threads com o kernel correspondente. Assim, foramescolhidos os algoritmos sumvector, gemm e o sincos.

4.1.1. Algoritmo Soma de Vetores - sumvector

O primeiro algoritmo utilizado foi o algoritmo soma de vetores do conjunto de exemplos daNVIDIA (CUDA Samples), esse conjunto vem com a instalação do kit de desenvolvimentoda plataforma CUDA. Foi utilizado inicialmente por ser um algoritmo simples e usado emtutoriais de programação paralela.

Seu funcionamento consiste, de três vetores (𝐴, 𝐵, 𝐶) de tamanho 𝑁 , sendo que,cada posição do vetor 𝐴 soma-se com a posição do vetor 𝐵, e o resultado é armazenado novetor 𝐶. No Código 4.1 pode-se visualizar a implementação do algoritmo soma de vetor nalinguagem de programação C.� �1 . . .2 int sumvector ( int a [N] , int b [N] ) {3 int c [N] , i ;4

5 for ( i =0; i<N; i++){6 c [ i ] = a [ i ] + b [ i ] ;7 }8 pr in t_ in t e ra coe s ( c ) ;9 }

10 . . .� �Código 4.1. Exemplo de código em C do algoritmo soma de vetor

O algoritmo no formato paralelo na versão CUDA, pode ser visualizado no Código 4.2.Seu funcionamento é comparável à implementação na linguagem de programação C, contudoo laço de repetição foi substituído pelo arranjo de threads. Durante a execução cada threadexecutará uma soma de um elemento de 𝐴 com um elemento de 𝐵. A condição na linha 6 do

Page 52: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

50

código assegura que não estão sendo executadas mais threads do que o tamanho da dimensãodos vetores, que neste caso é (𝑁).� �1 . . .2 __global__ void vecAdd (DATA_TYPE ∗a , DATA_TYPE ∗b , DATA_TYPE ∗c , int n ,

int funcId ) {3 //Thread ID4 int id = getGlobalIdFunc [ funcId ] ( ) ;5 i f ( id < n)6 c [ id ] = a [ id ] + b [ id ] ;7 }8 . . .� �

Código 4.2. Exemplo de código em CUDA do algoritmo soma de vetor

Por ser um algoritmo simples e de funcionamento de fácil compreensão, ele foiutilizado para explorarmos o problema da escolha das configurações, bem como demonstrarque realizar escolha aleatórias de configurações não é uma tarefa correta, pois pode levar àsubutilização dos recursos da GPU, causando a degradação do desempenho. Na Seção 5.1são mostrados os resultados obtidos através de execuções avulsas com escolhas aleatórias. Ocódigo completo escrito na linguagem C utilizando as bibliotecas do CUDA pode ser visto norepositório no GitHub3.

4.1.2. Algoritmo GEMMO GEMM é um algoritmo comum em Álgebra Linear, Aprendizado de Máquina, Estatísticae muitos outros domínios. Seu funcionamento consiste em três matrizes (𝐴,𝐵,𝐶) de tamanho𝑁 na qual a matriz 𝐶 é resultante de duas multiplicações sendo a primeira entre umaconstante 𝛼×𝐴𝐵 e depois o próprio 𝐶 multiplicado por uma constante 𝛽. Sua equação geralé apresentada da seguinte forma, 𝐶 ← 𝛼𝐴𝐵 + 𝛽𝐶 (POUCHET et al., 2012).

A implementação em C pode ser vista no Código 4.3, no qual foi utilizado três laçosde repetição onde os dois primeiros são utilizados para percorrer a matriz 𝐶 e realizar amultiplicação de cada valor da matriz 𝐶 com o valor declarado de beta. Após esse primeirolaço é realizado a multiplicação entre alpha com as matrizes 𝐴 e 𝐵 e logo após é realizado asoma com os valores da matriz 𝐶 e armazenado na própria matriz 𝐶.� �1 #define alpha 32412 ;2 #define beta 2123 ;3 . . .4 int gemm(DATA_TYPE ∗a , DATA_TYPE ∗b , DATA_TYPE ∗c , int ni , int nj , int nk ,

int alpha , int beta ) {

3 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/tree/master/benchmarks/sumvector/src>

Page 53: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

51

5 for ( i = 0 ; i < ni ; i++)6 for ( j = 0 ; j < nj ; j++){7 C[ i ] [ j ] ∗= beta ;8 for ( k = 0 ; k < nk ; ++k )9 C[ i ] [ j ] += alpha ∗ A[ i ] [ k ] ∗ B[ k ] [ j ] ;

10 }11 }12 . . .� �

Código 4.3. Exemplo de código em C do algoritmo GEMM

No Código 4.4 é apresentado o exemplo do kernel em CUDA. Seu funcionamentoconsiste primeiro na definição das constantes 𝛼 e 𝛽, aqui com valores estipulados pelabiblioteca do PolyBench. Após a declaração das constantes é declarado a função kernel querecebe como parâmetros os três vetores (𝑎, 𝑏, 𝑐) com os respectivos tamanhos (𝑁𝐼, 𝑁𝐽, 𝑁𝐾)e os laços de repetição que seriam utilizados para realizar as operações são trocados porarranjos de threads a partir da função getGlobalFunc. O restante do código é apresentado norepositório GitHub4.� �1 #define ALPHA 32412.0 f2 #define BETA 2123.0 f3 __global__ void gemm_kernel (DATA_TYPE ∗a , DATA_TYPE ∗b , DATA_TYPE ∗c , int

NI , int NJ, int NK, int funcId ) {4 int j = getGlobalIdFunc [ funcId ] ( ) ;5 int i = getGlobalIdFunc [ funcId ] ( ) ;6 i f ( ( i < NI ) && ( j < NJ) ) {7 c [ i ∗ NJ + j ] ∗= BETA;8 int k ;9 for ( k=0; k < NK; k++){

10 c [ i ∗ NJ + j ] += ALPHA ∗ a [ i ∗ NK + k ] ∗ b [ k ∗ NJ +j ] ;11 }12 }13 }� �

Código 4.4. Exemplo de código do kernel em CUDA do algoritmo GEMM

Com o algoritmo GEMM em funcionamento, foi criado o código para a ferramentaOpenTuner que será explicado na Seção 4.2. As seções 5.2.2 e 5.2.3 mostram respectivamenteos resultados obtidos pela ferramenta OpenTuner para o algoritmo GEMM, e também oresultado obtido através de testes por força-bruta.

4 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/blob/master/benchmarks/GEMM/gemm-occupancy/gemm.cu>

Page 54: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

52

4.1.3. Algoritmo de Cálculo da Tabela de Senos e Cossenos –sincos

O algoritmo sincos atualmente é implementado por benchmarks com propósitos matemáticos(álgebra linear) e também para desenvolvimentos de ferramentas como o KernelGen que temcomo objetivo geração automático de kernels paralelos.

Seu funcionamento é apresentado na Seção 3.2 (Ajuste do lado do software), a qualapresenta o sincos implementado na linguagem C (Código 3.1) e também suas versões dekernels para CUDA. Algumas versões de kernels foram geradas para sincos, essas versões sãoexplicadas na Tabela 3.3.

O sincos foi utilizado com o objetivo de mostrar as possibilidades de ajustes dolado do software, cada uma das versões de kernels faz a migração de iterações de uma dasdimensões dos laços aninhados. Os testes com essas versões foram realizados com auxílio doOpenTuner e as melhores configurações foram encontradas pelas heurísticas implementadaspelo OpenTuner com base nos resultados obtidos para as métricas coletadas. Na Seção 5.2.1são apresentados os resultados para as execuções com o sincos.

4.2. Desenvolvimento dos scripts para as execuçõescom o OpenTuner

Com a escolha dos algoritmos, o próximo passo foi desenvolver scripts em Python para aferramenta OpenTuner que tem como função a execução dos benchmarks com cada uma dasconfigurações e então escolher a melhor configuração com base no resultado de métricascoletadas do hardware pela ferramenta de perfilamento nvprof. Vale ressaltar que foi criadoum script para cada métrica e para cada algoritmo. Nesta seção será apresentado somente oscript desenvolvido para o algoritmo GEMM, os demais scripts podem ser consultados norepositório do GitHub5.

Como demonstrado na Seção 2.4.1, o OpenTuner trabalha em três passos, definiçãodo espaço de busca, método manipulator que realiza as escolhas e o método run que realizaa execução e a escolha do mélhor resultado a partir da métrica escolhida.

Na primeira versão desenvolvida para o OpenTuner no algoritmo GEMM foiespecificado o espaço de busca aberto na qual ele buscava todos os valores dentro de umespaço mínimo e máximo, esse mínimo e máximo é denotado por um bloco de parâmetrosque pode ser visto no Código 4.5.

5 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/tree/master/benchmarks>

Page 55: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

53

� �1 . . .2 BLOCO_PARAMETROS = [3 ( ’kernel’ , 0 , 0) ,4 ( ’gx’ , 1 ,2147483647) ,5 ( ’gy’ , 1 ,65535) ,6 ( ’gz’ , 1 ,65535) ,7 ( ’bx’ , 1 ,1024) ,8 ( ’by’ , 1 ,1024) ,9 ( ’bz’ , 1 ,64) ,

10 ( ’ni’ , 64 ,64) ,11 ( ’nj’ , 64 ,64) ,12 ( ’nk’ , 64 ,64) ,13 ( ’gpuId’ , 0 , 0)14 ]15 . . .� �

Código 4.5. Espaço de busca aberto implementado no OpenTuner

Com esse bloco de parâmetros criado o método run escolhia um valor dentro domínimo e máximo e realizava a execução do algoritmo GEMM para as configurações escolhidas.Contudo, na maneira de busca aberta ocasionava que a maioria das escolhas era escolhasinválidas (escolhas que não seguem as regras especificadas na Seção 3.1), ocasionando em testeserrados, bem como o tempo gasto para a execução era alto, fazendo com que mudássemos aforma de buscar as configurações.

Assim, foi desenvolvido uma segunda versão que buscaria somente no espaço debusca de configurações válidas. Desta forma foi criado primeiramente um script na linguagemC que escreve em um arquivo todas as configurações válidas para um tamanho 𝑁 , logo apóso OpenTuner cria uma lista destas configurações e encaminha para o método run que realizaos testes. O Código 4.6 apresenta parte do script desenvolvido em C para escrever em umarquivo as configurações válidas e o Código 4.7 mostra uma parte do arquivo criado pelo scriptem C. Pode ser visualizado todo o script e os arquivos gerados no repositório do GitHub6.� �1 . . .2 for ( bz = 1 ; bz <= min( i t e r a t i o n s ,MAX_BLOCK_Z) ; bz++) {3 for ( by = 1 ; by <= min ( ( i t e r a t i o n s / bz ) ,MAX_BLOCK_Y) ; by++) {4 for ( bx = 1 ; bx <= min ( ( ( i t e r a t i o n s / bz ) / by ) ,MAX_BLOCK_X) ; bx++) {5 for ( gx = 1 ; gx <= min ( ( ( ( i t e r a t i o n s / bz ) / by ) / bx ) ,MAX_GRID_X) ;

gx++) {6 for ( gy = 1 ; gy <= min ( ( ( ( ( i t e r a t i o n s / bz ) / by ) / bx ) / gx ) ,

MAX_GRID_Y) ; gy++) {7 for ( gz = 1 ; gz <= min ( ( ( ( ( ( i t e r a t i o n s / bz ) / by ) / bx ) / gx )

/ gy ) ,MAX_GRID_Z) ; gz++) {

6 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/tree/master/benchmarks/gen-configs>

Page 56: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

54

8 confBlock = bx ∗ by ∗ bz ;9 confGrid = gx ∗ gy ∗ gz ;

10 c o n f i g = confBlock ∗ confGrid ;11 // Evict ke rne l d ivergence , b locks with mult ip ly warp s i z e .12 i f ( ( confBlock <= 1024) && ( c o n f i g == i t e r a t i o n s ) && (

confBlock % 32 == 0) ) {13 p r i n t f ( " ’ gx:%d , gy:%d , gz :%d , bx:%d , by:%d , bz:%d , ’ \n " ,

gx , gy , gz , bx , by , bz ) ;14 countConf ig++;15 }16 }17 }18 }19 }20 }21 }22 . . .� �

Código 4.6. Espaço de busca aberto implementado no OpenTuner

� �1 . . .2 ’gx:1, gy:16, gz:8, bx:32, by:1, bz:1, ’3 ’gx:1, gy:32, gz:4, bx:32, by:1, bz:1, ’4 ’gx:1, gy:64, gz:2, bx:32, by:1, bz:1, ’5 ’gx:1, gy:128, gz:1, bx:32, by:1, bz:1, ’6 ’gx:2, gy:1, gz:64, bx:32, by:1, bz:1, ’7 . . .� �

Código 4.7. Parte do arquivo criado com as configurações válidas para N

Com a criação do espaço de busca é enviado uma lista para o método run com osvalores dos grids e blocos onde ele estará realizando os testes e os "cortes"que julgar necessárioatravés dos algoritmos de busca. Exemplo do método run é apresentado no Código 4.8. Comeste método funcionando o OpenTuner cria um comando em linha de comando no formatodo Código 5.2.� �1 . . .2 while True :3 c o n f i g u r a t i o n = d e s i r e d _ r e s u l t . c o n f i g u r a t i o n . data4 print "Configuration: " , c o n f i g u r a t i o n5 c f g = { match . group (1) : match . group (2 ) for match in re . f i n d i t e r ( r"([^:]+)

:(\S+)\s*,[ \n]" , c o n f i g u r a t i o n [ ’config’ ] ) }6 print "CFG: " , c f g7 confBlock = int ( c f g [ ’bx’ ] ) ∗ int ( c f g [ ’by’ ] ) ∗ int ( c f g [ ’bz’ ] )8 confGrid = int ( c f g [ "’gx" ] ) ∗ int ( c f g [ ’gy’ ] ) ∗ int ( c f g [ ’gz’ ] )

Page 57: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

55

9 c o n f i g = confBlock ∗ confGrid10 print "ConfBlock "+ str ( confBlock )11 print "ConfGrid " + str ( confGrid )12 i f ( ( confBlock <= 1024) and ( confBlock % 32 == 0) and ( c o n f i g == n) ) :13 break14 else :15 return Result ( time=FAIL_PENALTY)16 print "compiled: " , ’true’ i f compiled else ’false’17 i f not compiled :18 print "Compiling the program..."19 gcc_cmd = ’nvcc -I /usr/local/cuda/include -L /usr/local/cuda/lib64 -

ccbin=g++-6 gemm.cu -lcuda -lm -o gemm-cuda.exe’20 compi l e_resu l t = s e l f . cal l_program (gcc_cmd)21 a s s e r t compi l e_resu l t [ ’returncode’ ] == 022 print " OK.\n"23 global compiled24 compiled = not compiled25 run_cmd = ’nvprof --metrics achieved_occupancy ./gemm-cuda.exe’26 . . .� �

Código 4.8. Exemplo do método run para o algoritmo GEMM

Com a execução do comando gerado a partir do método run é enviado para o métodoget_metric_from_app_output que verifica o valor que foi gerado e retorna um valor damétrica que é usado para realizar a comparação e os "cortes"com os algoritmos de busca. Emnossa implementação neste método fica especificado a criação de um arquivo .csv que contémtodas as configurações e resultados gerados, no Código 4.9 é demonstrado a implementação dométodo get_metric_from_app_output. Quando encontrado a melhor configuração é geradoum arquivo .json contendo a melhor configuração.� �1 . . .2 def get_metric_from_app_output ( s e l f , app_output , c on f i gu ra t i on , kerne l ,

gpuId ) :3 metric_value = 0 .04 l i n e s = app_output . s p l i t ( "\n" )5 for cur r en t_ l ine in l i n e s :6 s t r g = "" + cur rent_ l ine7 i f s t r g . f i n d ( "Occupancy" ) > −1:8 idx = s t r g . index ( "Occupancy" )9 subs r tg = s t r g [ idx : ] . s p l i t ( " " )

10 print "substrg: " , subs r tg11 metric_value = f loat ( subs r tg [ 3 ] )12 print "achieved_occupancy: " , metr ic_value13 c o n f i g u r a t i o n = str ( c o n f i g u r a t i o n )

Page 58: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

56

14 c o n f i g u r a t i o n = c o n f i g u r a t i o n . r e p l a c e ( "{" , str ( k e rne l )+"," ) . r e p l a c e ( ":" , "" ) . r e p l a c e ( "}" , "" )

15 c o n f i g u r a t i o n = c o n f i g u r a t i o n . r e p l a c e ( "’gx" , "" ) . r e p l a c e ( "’gy’" , "" ) .r e p l a c e ( "’gz’" , "" ) . r e p l a c e ( "’bx’" , "" ) . r e p l a c e ( "’by’" , "" ) . r e p l a c e ( "’bz’" , "" ) . r e p l a c e ( "’" , "" ) . r e p l a c e ( "\"" , "" )

16 r e su l t ado = metric_value17 arquivo_csv = open( "diretorio_saida"+str ( sys . argv [ 2 ] )+".csv" , "a" )18 arquivo_csv . wr i t e ( "Kernel ,gx,gy,gz,bx,by,bz,gpuId ,occupancy \n" )19 arquivo_csv . wr i t e ( str ( c o n f i g u r a t i o n )+","+str ( gpuId )+","+str ( r e su l t ado )+"

\n" )20 return metric_value21 . . .� �

Código 4.9. Exemplo do método get_metric_from_app_output para o algoritmo GEMM

Com o funcionamento exato do código é criado um arquivo .csv contendo asconfigurações e também um arquivo .json com a melhor configuração encontrada. NoCódigo 4.10 é visto exemplo dos dois arquivos para 𝑁 = 64 para a métrica achieved_occupancy.� �1 . . . Arquivo . csv2 Kernel , gx , gy , gz , bx , by , bz , gpuId , occupancy3 0 , 4 , 2 , 2 , 32 , 2 , 4 , 0 , 0 . 93034 0 ,8 , 2 , 4 , 8 , 4 , 2 , 0 , 0 . 9306345 0 ,2 , 1 , 16 , 1 , 128 ,1 , 0 , 0 . 9321546 . . .7 . . . Arquivo . j son8 {"ni" : 64 , "nj" : 64 , "nk" : 64 , "kernel" : 0 , "gpuId" : 0 , "config" : "’gx:64,

gy:1, gz:2, bx:1, by:2, bz:16, ’ \n"}9 . . .� �

Código 4.10. Parte do arquivo criado com as configurações válidas para N

Para uma melhor organização foi criado um código OpenTuner para cada métricaque foi utilizada para gerar resultados, no presente texto é apresentado somente parte docódigo para a métrica achieved_occupancy, para visualizar os outros códigos bem como estecódigo completo, pode ser visualizado no repositório do GitHub7.

Vale ressaltar que na próxima Seção 4.3 é apresentado as GPUS que foram utilizadaspara os testes e também as métricas utilizadas para a escolha da melhor configuração noOpenTuner.

7 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/tree/master/benchmarks/GEMM>

Page 59: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

57

4.3. Realização dos Testes e Extração da Melhor Con-figuração

Com a escolha dos algoritmos, e o desenvolvimento dos códigos para o OpenTuner, foiespecificado quais métricas deveriam ser utilizados para a escolha da melhor configuração.Essas métricas são da ferramenta nvprof que a partir de uma execução de linha de comando(especificado no Código 5.2) é retornado um valor ou uma porcentagem dependendo da métricaescolhida. As métricas que foram escolhidas para determinar as melhores configurações dopresente trabalho são:

• sm_efficiency: porcentagem de tempo que pelo menos um warp está ativo nomultiprocessador.

• achieved_occupancy: razão entre a média de warps ativos por ciclo com o máximonúmero de warps suportado no multiprocessador.

• ipc: instruções executadas por ciclo.• inst_per_warp: número médio de instruções executados por cada warp.• gld_efficiency: proporção da taxa de transferência solicitada da memória global

(load) para a taxa de transferência na memória global necessária.• gst_efficiency: proporção da taxa de transferência de armazenamento na memória

global (store) solicitada pela taxa de transferência de armazenamento de memóriaglobal necessária.

Para ter uma comparação de arquiteturas, os testes foram executados em três GPUsque são da arquitetura Kepler e da arquitetura Pascal. Desta forma estará comparandoquais as melhores configurações de kernel para a determinada arquitetura. A Figura 4.2apresenta as configurações das três GPUs escolhidas.

Figura 4.2. Arquiteturas que serão utilizadas nos experimentos

A partir da execução dos testes para os algoritmos explicados nas seções anteriores,o próximo passo é encontrar padrões ou tendências de configurações. A Seção 5.1, mostra osresultados obtidos a partir de escolhas avulsas para o algoritmo soma de vetor, as Seções 5.2.1,

Page 60: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

58

5.2.2, 5.2.3 e 5.2.4 mostram os resultados obtidos com o auxílio da da ferramenta OpenTunerpara os algoritmos sincos e GEMM, bem como apresenta resultados obtidos através de forçabruta para os dois algoritmos.

4.4. Detecção de Padrões ou Tendências de Configura-ção

Assim que concluído todos os testes, foi pesquisado uma forma de encontrarmos um padrão ouuma tendência de configuração a partir de todos os dados que tínhamos dos testes realizados.Desta forma, foi realizado uma análise dos dados, com o auxílio da linguagem de programaçãoR. No Código 4.11 é apresentado parte do script criado para a análise de dados, todo orestante do script pode ser encontrado no GitHub8.� �1 . . .2 mypath <− "/home/tcc_cuda_opentuner_joao/pattern_IA/testes/gemm-

smefficiency -512-todas -conf-gtx780.csv"34 dados <− read . csv (mypath , header = T, sep = "," )5 i s . data . frame ( dados )6 head ( dados )7 s t r ( dados )8 summary( dados )9

10 # adic iona in t e racao entre g e b11 dados <− transform ( dados ,12 g=interaction ( gx , gy , gz ) ,13 b=interaction (bx , by , bz ) )1415 # limpa os n i v e i s nao u t i l i z a d o s16 dados <− d r o p l e v e l s ( dados )17 . . .18 ## usando funcoes da b i b l i o t e c a l a t t i c e19 l ibrary ( l a t t i c e )2021 x11 ( )22 xyplot ( s m e f f i c i e n c y ~ g , data = dados ,23 as . table = TRUE,24 s c a l e s = l i s t ( y = l i s t ( cex = 1) ,25 x = l i s t ( cex = 0 . 5 , ro t = 45) )26 # layou t = c (22 ,20)27 )28

8 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/blob/master/pattern_IA/testes/script.r>

Page 61: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

59

293031 dados$cut . e f i c <− with ( dados , cut ( sme f f i c i en cy ,32 breaks = c (0 ,18 , 30 , 60 , 80 , 100) ) )3334 with ( dados , table ( cut . e f i c ) )3536 dados . 8 0 . 1 0 0 <− subset ( dados , cut . e f i c == "(80,100]" )37 . . .� �

Código 4.11. Parte do script em R criado para análise de dados.

Primeiro foi verificado a validade dos dados através da função is.data.frame, destaforma ele especifica o cabeçalho do arquivo .csv e aplica-se a função sumarização para verificaros formatos dos dados do dataframe.

Com a sumarização criamos dentro do próprio dataframe uma combinação (chamadade interaction) combinando todos os valores de grids para a variável 𝑔 e os blocos paraa variável 𝑏. Após a combinação foi feito a limpeza dos níveis não utilizados e com estalimpeza foi chamado a função xyplot que foi passado como parâmetro os valores da métricasm_efficiency, combinando com os dados. No repositório do GitHub9 pode visualizar todo oscript desenvolvido.

Contudo com os experimentos realizados não conseguimos encontrar padrões etendências de configuração, na Seção 5.2.5 é demonstrado os resultados obtidos até o momento.

4.5. Considerações FinaisNeste capítulo foi apresentado a metodologia aplicada para a realização deste trabalho.Foi apresentado as bibliotecas de algoritmos que serão utilizados, como foi realizado odesenvolvimento dos script para os testes com a ferramenta OpenTuner, a realização dostestes que apresentou as métricas para escolha das configurações e as GPUs usadas noexperimento. Por fim, é explicado como foi feito a procura por padrões ou tendências deconfiguração.

Mais detalhes dos experimentos realizados e dos resultados obtidos são apresentadosno Capítulo 5.

9 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/blob/master/pattern_IA/testes/script.r>

Page 62: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Capítulo

5Experimentos e Resultados

Durante o desenvolvimento deste trabalho foram executados alguns experimentos. Experimen-tos iniciais com execuções avulsas para verificações básicas e foram executados experimentoscom alguns benchmarks selecionados de acordo com o critério de possuírem um conjunto delaços aninhados. A execução dos experimentos foi feita com base nos passos estabelecidos noCapítulo 4 e os resultados obtidos apresentados neste Capítulo.

5.1. Primeiros ResultadosEsta seção tem como finalidade exibir os primeiros resultados obtidos. A Seção 5.1.1 foiutilizado o algoritmo soma de vetores. A simplicidade desse algoritmo permite mostrar que,mesmo em casos simples, se o desenvolvedor fizer uma escolha aleatória para os parâmetrosda configuração do arranjo de threads, esta escolha poderá não ser uma das melhoresconfigurações.

A Seção 5.1.2 apresenta a ideia das diferentes dimensões do arranjo de threadse também apresenta alguns resultados nos quais esta diferença se torna perceptível pelautilização de kernels com códigos distintos. Por fim, a Seção 5.1.3 mostra resultados obtidosutilizando a ideia de ajustar as configurações de kernels, pelos métodos de força bruta e pelouso da ferramenta de autotuning OpenTuner.

5.1.1. Experimento com execuções avulsas para o Soma de Vetores

Foi criado um experimento inicial para verificar a dificuldade em encontrar a melhorconfiguração de kernel para uma arquitetura. Nesse primeiro experimento foi usado oalgoritmo de soma de vetores, que tem sido utilizado em tutoriais de programação paralelapor ser um algoritmo simples e fácil de verificar a divisão de trabalho pelas threads, o

60

Page 63: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

61

funcionamento do algoritmo soma de vetor é explicado na Seção 4.1.1.Para exemplificar a complexidade na busca pela melhor configuração foi escolhido

𝑁 = 131072 para o tamanho dos vetores. Esse valor foi escolhido por ser um tamanhoconsiderável médio e que apresenta resultados satisfatórios em curto tempo de execução.Neste experimento foram escolhidas configurações aleatórias dentro de todas as possibilidadespara o tamanho 131072. Para este tamanho há em torno de 13761 configurações possíveis deserem feitas, sendo que foram escolhidas para os testes duas configurações de cada dimensão(1D_1D, 2D_2D e 1D_3D). Assim, os testes foram realizados escolhendo-se as configurações demaneira aleatória e verificamos que não se consegue a configuração ideal para o algoritmo e aarquitetura em questão.

O experimento foi executado em duas das três GPUs apresentadas na Figura 4.2 e amétrica escolhida para a execução foi a achieved_occupancy que representa a ocupação dosmultiprocessadores, retornando a relação média de warps ativos por execução em relação aotamanho máximo suportado em um multiprocessador. Os resultados para o experimento como soma de vetores são apresentados na Tabela 5.1.

Tabela 5.1. Resultados do Experimento soma de vetor

NGTX 780 - Kepler TitanX - Pascal

Configuração Resultado Configuração Resultado131072 (1024, 1, 1),(1, 128, 1) 82, 68% (1024, 1, 1),(1, 128, 1) 84, 76%131072 (1, 1024, 1), (128, 1) 83, 34% (1, 1024, 1), (128, 1) 78, 15%131072 (128, 1, 1), (1, 16, 64) 87, 00% (128, 1, 1), (1, 16, 64) 86, 44%131072 (256, 1, 1), (1, 8, 64) 83, 37% (256, 1, 1), (1, 8, 64) 88, 61%131072 (128, 1, 1), (2, 8, 64) 81, 22% (128, 1, 1), (2, 8, 64) 86, 67%131072 (128, 1, 1), (2, 8, 64) 81, 42% (128, 1, 1), (2, 8, 64) 86, 92%131072 (32, 128, 1), (1, 1, 32) 21, 10% (32, 128, 1), (1, 1, 32) 23, 14%131072 ( 1, 32, 128), (1, 1, 32) 21, 01% ( 1, 32, 128), (1, 1, 32) 22, 50%131072 ( 1, 16, 8), (1, 16, 64) 84, 42% ( 1, 16, 8), (1, 16, 64) 78, 29%131072 ( 1, 64, 2), (1, 16, 64) 84, 31% ( 1, 64, 2), (1, 16, 64) 85, 41%131072 (16, 1, 8), (4, 4, 64) 82, 91% (16, 1, 8), (4, 4, 64) 85, 76%131072 (128, 1, 2), (2, 4, 64) 84, 02% (128, 1, 2), (2, 4, 64) 88, 60%131072 (64, 16, 2), (1, 1, 64) 41, 99% (64, 16, 2), (1, 1, 64) 57, 29%131072 ( 2, 256, 8), (1, 1, 32) 21, 11% ( 2, 256, 8), (1, 1, 32) 22, 72%131072 ( 4, 16, 2), (1, 16, 64) 83, 99% ( 4, 16, 2), (1, 16, 64) 85, 90%131072 (32, 2, 2), (1, 64, 16) 82, 40% (32, 2, 2), (1, 64, 16) 85, 42%131072 ( 2, 32, 2), (4, 4, 64) 82, 32% ( 2, 32, 2), (4, 4, 64) 86, 74%131072 (16, 4, 2), (2, 8, 64) 82, 98% (16, 4, 2), (2, 8, 64) 87, 12%

Page 64: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

62

Fica evidente que escolhendo aleatoriamente configurações para um tamanho 𝑁 éimprovável que encontre a melhor configuração para métrica achieved_occupancy, pois paraesta métrica os melhores resultados teriam valores o mais próximo de 100%. Atingindo umataxa elevada de ocupação dos multiprocessadores e de seus recursos.

Diante da dificuldade de se encontrar uma boa configuração de maneira aleatória,considerando o número de configurações que precisariam ser testadas, o processo manualtorna-se inviável. Então optou-se por automatizar inicialmente via scripts e depois com o usode ferramenta de autotuning que mostrou-se uma alternativa interessante, pois a ferramentaexplora o espaço de soluções através de buscas e ao final do processo encontra a melhorconfiguração com base nos resultados da métrica considerada. As seções seguintes apresentamos experimentos iniciais.

5.1.2. Experimento com execuções avulsas para o sincos

Também para exemplificar o quanto que as dimensões são utilizadas, foi executadoexperimentos com a métrica achieved_occupancy que na qual mostrou as médias de warpsativos durante a execução. Para essa amostra foi utilizado as duas GPUs da Figura 4.2 dearquiteturas diferentes para uma comparação do uso de toda a capacidade da arquitetura.Os resultados são apresentados na Tabelas 5.2 e 5.3.

Tabela 5.2. Média de warps ativos na execução do algoritmo sincos

GTX-780 - Kepler𝑛𝑥, 𝑛𝑦, 𝑛𝑧 Kernel Config Dimens. Result576 0 (576,32,18),(32,18,1) 3D_2D 75%576 1 (32,18,1),(32,18,1) 2D_2D 82%576 2 (1,1,1),(32,18,1) 1D_2D ERROR576 3 (1,1,1),(1,1,1) 1D_1D ERROR

Tabela 5.3. Média de warps ativos na execução do algoritmo sincos

Titan X - Pascal𝑛𝑥, 𝑛𝑦, 𝑛𝑧 Kernel Config. Dimens. Result960 0 (960,32,30),(32,30,1) 3D_3D 78%960 1 (30,32,1),(30,32,1) 2D_2D 93%960 2 (1,1,1),(32,30,1) 1D_2D 45%960 3 (1,1,1),(1,1,1) 1D_1D 1%

Na Tabela 5.2 foi utilizado o tamanho 576 para as iterações (𝑛𝑥, 𝑛𝑦, 𝑛𝑥). Este valorfoi utilizado por ser o máximo que a memória do dispositivo possibilita, sendo que usando o

Page 65: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

63

tamanho em 576, foram utilizados 2, 29 GBs de um total disponível de 3 GBs. O kernel 1 foio que obteve-se o melhor resultado, sendo que, o kernel 2 as iterações 𝑛𝑥, 𝑛𝑦 serão executadospelas threads, desta forma, com as divisões de grids e blocos no formato mostrado, houveuma utilização de 82% dos warps ativos na execução.

Já na Tabela 5.3 foi utilizado o tamanho de 960 pois neste dispositivo possui umamemória de 12 GBs e neste teste foram utilizados 10 GBs. O kernel 1 foi que obteve melhorutilização de warps, este resultado é explicado pela divisão de threads para as iterações de𝑛𝑥, 𝑛𝑦, essa divisão também pode explicar porque o kernel 3 obteve o pior desempenho,sendo que sua divisão de grids e blocos foi o mínimo (1 em todos os casos), desta formasomente um bloco de thread irá executar os laços.

5.1.3. Experimentos iniciais de automatização por força bruta

Visando automatizar a execução dos testes de configurações (grid, bloco, threads),inicialmente desenvolveu-se um código para gerar scripts bash que disparassem a execuçãodos benchmarks, por meio do método de força bruta. Neste método é executado todas asconfigurações possíveis e ao final compara-se o resultado obtido para encontrar a melhorconfiguração.

Nesse primeiro experimento foi utilizada a linguagem de programação C, por seruma linguagem compilada o que torna a execução mais rápida e também por ser umalinguagem bem consolidada atualmente, o Código 5.1 apresenta a codificação realizada parao experimento por força bruta.

Primeiro foram definidos os tamanhos máximos dos blocos e grids (linhas 5 - 10),esses valores são os apresentados pela arquitetura que será utilizada para o experimento.Após definir os tamanhos dos grids e blocos foi definido uma função mínimo que realiza acomparação e escolhe o menor tamanho, esta função é utilizada nos laços para escolher omínimo entre o número de iterações que o algoritmo irá realizar com o máximo dos blocos egrids.

Na função principal (linhas 13 − 44) é desenvolvido todo o algoritmo, sendo que,primeiro declarado as variáveis que serão utilizadas para armazenar as configurações (gx, gy,gz, bx, by e bz), também as variáveis (confGrid, config, contConfig e confBlock) querespectivamente armazenavam a multiplicação entre os grids, a multiplicação entre blocos egrids, o total de configurações possíveis e a multiplicação dos blocos.

A parte da geração das configurações está no laços entre as linhas 22− 42, sendoque, cada laço gera a configuração para um bloco ou grid. Por exemplo o primeiro laço (linha22) realiza a iteração de 1 até o menor valor entre o tamanho do vetor 𝑛 e o MAX_BLOCK_Z.Nos demais laços é realizado o mesmo formato, porém com uma diferença que é a divisão de𝑛 pelo valor encontrado no laço anterior e a partir desta divisão se encontra o menor valor

Page 66: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

64

com o máximo de grids ou blocos. Este formato de iteração juntamente com a condição nalinha 31 garante que será criado somente configurações válidas.� �1 #include <s t d i o . h>2 #include <s t d l i b . h>3 #include <math . h>4

5 #define MAX_BLOCK_X 10246 #define MAX_BLOCK_Y 10247 #define MAX_BLOCK_Z 10248 #define MAX_GRID_X 21474836479 #define MAX_GRID_Y 65535

10 #define MAX_GRID_Z 6553511 #define min (x , y ) ( ( x )<(y ) ?( x ) : ( y ) )12

13 int main ( int argc , char const ∗ argv [ ] ) {14 unsigned long long int gx , gy , gz , bx , by , bz , confBlock ;15 unsigned long long int confGrid , con f i g , contConf ig ;16 unsigned int n ;17 n = a t o i ( argv [ 1 ] ) ;18 confBlock = 0 ;19 confGrid = 0 ;20 c o n f i g = 0 ;21 contConf ig = 0 ;22 for ( bz = 1 ; bz <= min (n , MAX_BLOCK_Z) ; bz++){23 for ( by = 1 ; by <= min ( ( n / bz ) , MAX_BLOCK_Y) ; by++){24 for ( bx = 1 ; bx < min ( ( ( n / bz ) / by ) , MAX_BLOCK_X) ; bx++){25 for ( gx = 1 ; gx <= min ( ( ( ( n / bz ) / by ) / bx ) ,MAX_GRID_X) ; gx++){26 for ( gy = 1 ; gy <= min ( ( ( ( ( n/ bz ) / by ) / bx ) / gx ) ,MAX_GRID_Y) ; gy++){27 for ( gz =1; gz <= min ( ( ( ( ( ( n / bz ) /by ) / bx ) / gx ) / gy ) ,MAX_GRID_Z) ; gz++){28 confBlock = bx ∗ by ∗ bz ;29 confGrid = gx ∗ gy ∗ gz ;30 c o n f i g = confBlock ∗ confGrid ;31 i f ( ( confBlock <= 1024) && ( c o n f i g == n) && ( confBlock% 32 ==0)) {32 p r i n t f ( " (%4d,%4d,%4d,%4d,%4d,%4d ) \n" , gx , gy , gz , bx , by , bz ) ;33 contConf ig++;34 }35

36 }37 }38 }39 }40 }41 }42 return (0 ) ;43 }� �

Código 5.1. Exemplo de algoritmo para encontrar melhor configuração por força-bruta

A partir da geração das configurações é executado o código do benchmark implemen-tado em CUDA com os parâmetros sendo os valores gerados pelo Código 5.1 juntamente coma métrica achieved_occupancy, o Código 5.2 mostra como é a execução por linha de comandoda soma de vetor com as configurações e as métricas.

Page 67: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

65

� �1 nvprof --metrics achieved_occupancy ./ sumvector -cuda <kernel > <gx > <gy > <gz > <bx > <by > <

bz > <n> <dimensao > <gpu >� �Código 5.2. Formato de execução da soma de vetor em CUDA com as configurações geradas

Contudo, o método de escolha por força bruta não é de longe a melhor solução,pois para determinados tamanhos de 𝑛 a busca se torna complexa e a escolha da melhorsolução não é encontrada em tempo hábil. Por exemplo, somente para gerar as configuraçõespara o tamanho de 𝑛 = 131072 foram gastos cerca de 5 minutos, e para tamanhos de 𝑛

maiores a geração e a execução pode chegar a meses. Desta forma, uma maneira maisadequada de se encontrar a melhor configuração é utilizando-se ferramentas de autotuning,pois estas utilizam-se de algoritmos de busca que realizam escolhas com base em heurísticaspré-determinadas que exploram o espaço de configurações mais eficientemente.

5.2. ExperimentosEssa seção apresenta os resultados gerados pelo algoritmo sincos e GEMM com o uso daferramenta OpenTuner. O algoritmo sincos apresentou valores satisfatórios com até possíveisvisualizações de padrões ou tendências de configuração. O algoritmo GEMM demonstrouvalores considerados bons, contudo por ser um algoritmo que não usa uma intensidadecomputacional alta, trouxe valores abaixo do esperado.

5.2.1. Experimento 1 com OpenTuner: SincosAs Seções a seguir é discutido respectivamente os resultados dos testes do algoritmo sincoscom as métricas gld_efficiency, gst_efficiency, inst_per_warp, ipc, achieved_occupancye sm_efficiency. Todos os resultados gerados, podem ser visualizados no repositório doGitHub10, sendo que todas as configurações testadas foram armazenadas em arquivos noformato .csv e os melhores resultados foram armazenados em arquivos no formato .json.

Resultados do algoritmo Sincos com a métrica gld_efficiency

Segundo Cheng et al. (2014), usando-se a métrica gld_efficiency é retornado a taxa detransferência solicitada da memória global para a taxa de transferência da memória globalnecessária, isto é, mede o quão bem as operações de carregamento do kernel usam a largurade banda da memória do dispositivo, assim para validarmos que a configuração de fato estáno seu melhor desempenho, esta tem que obter o resultado próximo a 100%.

As melhores configurações obtidas para a métrica gld_efficiency nas GPUS - TitanX,GTX1070 e GTX780 são apresentadas nas Tabelas 5.4, 5.5 e 5.6. Vale ressaltar que a ferramenta

10 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/tree/master/results>

Page 68: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

66

OpenTuner retorna somente uma configuração como a melhor configuração, assim, pode haveroutras configurações que obtiveram o mesmo valor e que não foram listadas na tabela.

Tabela 5.4. Sincos métrica gld_efficiency GPU-TitanX

N Kernel gx gy gz bx by bz gld_efficiency64 0 1 1 4 1 32 32 90.28%96 0 6 2 8 2 3 16 90.28%

128 0 1 4 64 4 2 8 90.28%160 0 160 1 5 8 2 2 90.28%192 0 4 4 4 1 72 8 90.28%224 0 1 4 98 2 1 64 90.28%256 0 2 1 128 1 64 4 90.28%288 0 18 18 2 16 1 8 90.28%320 0 1 5 320 2 32 1 90.28%352 0 1 4 88 11 2 16 90.28%

Tabela 5.5. Sincos métrica gld_efficiency GPU-GTX-1070

N Kernel gx gy gz bx by bz gld_efficiency64 0 2 2 4 4 4 32 90.28%96 0 3 3 1 512 2 1 90.28%

128 0 8 1 16 4 2 32 90.28%160 0 10 1 4 16 20 2 90.28%192 0 4 2 36 32 2 2 90.28%224 0 1 14 16 2 28 4 90.28%256 0 1 8 32 2 128 1 90.28%288 0 16 9 2 1 48 6 90.28%320 0 8 1 16 10 2 40 90.28%512 0 11 16 1 8 22 4 90.28%

Para todos os tamanhos de 𝑁 obteve-se o resultado de 90, 28% de uso da memóriaglobal da GPU, contudo houve uma variância de valores entre 12.5% a 90.28%.

Por exemplo, a configuração (1, 1, 4, 1, 32, 32) para 𝑁 = 64 obteve-se o valor de90, 28%, contudo, se verificarmos as configurações (1, 1, 4, 32, 1, 32) e (1, 1, 4, 32, 32, 1), estasobtiveram o valor de 12, 5%. Assim como quando foram modificados os valores das dimensõespara o grid obteve-se valores de 12, 5%, como no caso da configuração (1, 1, 32, 32, 4, 1). Essasdiferenças ocorrem também para outros 𝑁𝑠, como exemplo para 𝑁 = 352 sendo que amelhor configuração foi (4, 2, 44, 4, 2, 44) com 90, 28%, mudando as configurações de blocos(4, 2, 44, 2, 4, 44) e (4, 2, 44, 44, 2, 4) ambos obtém o valor de 12, 5%. Uma possível respostaestá embasado por Cheng et al. (2014), para essa mudança se deve ao fato que os valores dosblocos são maiores que um warp, sendo que para melhorar o desempenho a dimensão maisinterna deve ser um múltiplo do tamanho do warp, isto é múltiplo de 32.

Page 69: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

67

Tabela 5.6. Sincos métrica gld_efficiency GPU-GTX-780

N Kernel gx gy gz bx by bz gld_efficiency64 0 4 2 16 4 1 8 90.28%96 0 4 4 1 3 32 6 90.28%

128 0 4 32 4 2 8 2 90.28 %160 0 4 4 2 2 10 40 90.28 %192 0 32 1 6 4 1 48 90.28%224 0 4 8 7 2 56 2 90.28%256 0 4 2 16 128 4 1 90.28%288 0 1 648 1 2 8 8 90.28%320 0 1 40 5 16 4 8 90.28%352 0 4 2 44 4 2 44 90.28%

Resultados do algoritmo Sincos com a métrica gst_efficiency

De acordo com Cheng et al. (2014), a métrica gst_efficiency retorna a porcentagem de uso damemória global de armazenamento (store), assim nas Tabelas 5.7, 5.8 e 5.9 são apresentandasas melhores configurações para as GPUs que foram usadas para os experimentos.

Tabela 5.7. Sincos métrica gst_efficiency GPU-TitanX

N Kernel gx gy gz bx by bz gst_efficiency64 0 1 1 128 2 4 4 100.0%96 0 8 2 1 8 9 8 100.0%

128 0 4 1 16 1 8 32 100.0%160 0 5 4 5 2 2 64 100.0%192 0 12 1 4 8 2 48 100.0%224 0 98 1 1 32 2 8 100.0%256 0 16 2 16 32 4 1 100.0%288 1 6 24 1 4 9 16 100.0%320 0 400 1 8 2 4 4 100.0%352 0 4 121 2 2 4 16 100.0%

Assim como para a métrica gld_efficiency, a métrica gst_efficiency retornou valoresinteressantes. Para todos os 𝑁𝑠 nas GPUs TitanX e GTX1070 foram retornados o máximode uso da memória global (store) com valores em 100%, contudo para a GPU GTX-780houve variações para os valores de 𝑁 = 64, 96, 128, 160, essa variação pode ser explicada pelotamanho menor de memória da GPU GTX-780 comparada com as GPUs TitanX e GTX-1070.

Outro dado interessante é quanto mais independência da memória, isto é, quantomais se retirar dependência de laços, melhor será o uso da memória global (store) Cheng etal. (2014), isso explica porque com o kernel_0 obteve-se os melhores resultados, sendo queos laços mais internos foram transferidos para o arranjo de threads.

Page 70: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

68

Tabela 5.8. Sincos métrica gst_efficiency GPU-GTX-1070

N Kernel gx gy gz bx by bz gst_efficiency64 0 4 2 16 32 2 1 100.0%96 0 3 2 12 16 1 8 100.0%

128 0 1 128 2 4 1 16 100.0%160 0 2 5 10 64 1 4 100.0%192 0 16 12 6 2 8 2 100.0%224 0 1 2 56 64 7 1 100.0%256 0 4 1 64 2 64 2 100.0%288 0 3 6 8 6 32 3 100.0%320 0 2 5 20 8 4 16 100.0%

Tabela 5.9. Sincos métrica gst_efficiency GPU-GTX-780

N Kernel gx gy gz bx by bz gst_efficiency64 0 2 2 1 1 512 2 88.89%96 0 12 3 1 1 64 4 84.21%

128 0 2 32 1 1 64 4 84.21%160 0 100 2 1 1 64 2 88.89%192 0 2 12 2 12 16 4 100.0%224 0 1 224 1 7 16 2 100.0%256 0 1 4 64 128 1 2 100.0%288 0 3 2 72 4 12 4 100.0%320 0 8 8 5 1 320 1 100.0%352 0 121 1 2 8 64 1 100.0%

Resultados do algoritmo Sincos com a métrica inst_per_warp

A métrica inst_per_warp mostra as instruções executadas por warp em cada multiprocessador.Altas variações nestes valores indicam cargas de trabalhos não uniformes para os blocos degrids do kernel.

Segundo Cheng et al. (2014), embora tal desequilíbrio não tenha necessariamenteque resultar em um baixo desempenho, a métrica instructions per warp é útil para verificarvariações na atividade do SM. O padrão de código mais comum para causar grandes variaçõesnas instructions per warp é blocos de código que são condicionalmente executados, nos quaisa expressão condicional depende do valor anterior.

Ainda de acordo com o que foi explicado por Cheng et al. (2014), as configuraçõesque alcançaram valores próximos a 100 são ideais, por exemplo, para todas as configuraçõesapresentadas na Tabela 5.10 e 5.11 alcançaram valores 100 ou próximos a isso.

Para a GPU GTX-780 (Tabela 5.12), houve valores que extrapolaram o limitequestionado por Cheng et al. (2014), por exemplo o menor uso de instruções para a GTX-780foi a configuração (4, 1, 32, 2, 8, 8) para 𝑁 = 128 com o valor de 95 instruções por warp.Para valores como 𝑁 = 320 alcançou 22746, muito acima do normal. Questões arquiteturaiscomo por exemplo a GPU GTX-780 ser da arquitetura Kepler pode ser um fator, bem como

Page 71: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

69

Tabela 5.10. Sincos métrica inst_per_warp GPU-TitanX

N Kernel gx gy gz bx by bz inst_per_warp64 0 2 16 2 1 32 2 100.096 0 24 3 2 8 1 8 100.0

128 0 2 16 2 16 16 1 100.0160 0 8 2 10 40 1 4 100.0192 0 8 2 3 32 24 1 100.0224 0 7 14 16 2 16 1 100.0256 0 4 4 4 2 512 1 100.0288 0 3 16 3 8 72 1 100.0320 0 40 5 8 4 16 1 100.0

Tabela 5.11. Sincos métrica inst_per_warp GPU-GTX-1070

N Kernel gx gy gz bx by bz inst_per_warp64 0 2 4 2 128 2 1 104.096 0 4 4 18 1 8 4 100.0

128 0 4 16 4 8 1 8 100.0160 0 100 2 4 4 8 1 100.0192 0 2 24 24 1 4 8 100.0224 0 1 784 1 64 1 1 88.0256 0 512 1 1 128 1 1 88.0288 0 4 18 6 64 3 1 100.0320 0 5 10 4 1 32 16 100.0

Tabela 5.12. Sincos métrica inst_per_warp GPU-GTX-780

N Kernel gx gy gz bx by bz inst_per_warp64 1 8 1 2 1 256 1 4570.096 1 1 1 12 256 3 1 6842.0

128 0 4 1 32 2 8 8 95.0160 1 80 1 1 5 1 64 11386.0192 1 96 6 1 64 1 1 13658.0224 1 1 28 28 1 2 32 15932.0256 1 1 64 32 1 1 32 18202.0288 1 2 1 108 8 48 1 20476.0320 1 1 16 100 1 1 64 22746.0

tamanho de memória comparado as outras arquiteturas.

Resultados do algoritmo Sincos com a métrica ipc

A métrica ipc mostra o número máximo de instruções executadas em um único ciclo. Destaforma, números mais altos, isto é, próximo a 1.0 significam uso mais eficiente da GPU que éutilizada NVIDIA (2015b). Contudo, valores acima de 1.0 significam que há algum overclocke valores acima de 2.0 está com algum erro que faz o aumento do uso de instruções por ciclo.

Page 72: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

70

Na Figura 5.1 são apresentadas estatísticas do número de instruções por ciclo em uma GPU,os valores considerados issued são instruções emitidas e executed são instruções executadas.

Figura 5.1. Estatísticas de uso de instruções por ciclo. Fonte: (NVIDIA, 2015b)

Tabela 5.13. Sincos métrica ipc GPU-TitanX

N Kernel gx gy gz bx by bz ipc64 1 2 4 1 1 8 64 0.66835996 1 3 6 1 1 8 64 1.021204

128 1 8 16 1 1 8 16 0.955215160 1 16 5 1 1 8 40 1.00523192 1 4 32 1 1 8 36 1.028021224 0 28 7 1 1 8 32 0.96613256 0 8 8 1 4 64 4 1.11104288 0 6 54 1 4 2 32 1.128665320 0 1 10 10 32 16 2 1.088225

Seguindo o especificado por NVIDIA (2015b), para todos os 𝑁𝑠 houve valorespróximos a 1.0 e alguns obteve-se valores superiores a 1.0, por exemplo, na Tabela 5.15obteve-se o valor de 1.621145 instruções por ciclo de clock.

Para esta métrica, foi verificado vários valores de instruções por ciclo de clock, porexemplo, para a GPU TitanX com 𝑁 = 128 as configurações (2, 2, 4, 2, 256, 2) houve 0.135871instruções por ciclo de clock, variando somente os blocos (2, 2, 4, 4, 64, 4), (2, 2, 4, 1, 64, 16) e(2, 2, 4, 128, 2, 4) atingiu valores próximos como 0.135717, 0.134141 e 0.132853.

Comparando-se com a configuração que registrou o maior número de instruções por

Page 73: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

71

Tabela 5.14. Sincos métrica ipc GPU-GTX-1070

N Kernel gx gy gz bx by bz ipc64 1 2 2 1 64 8 2 0.71916596 1 4 18 1 1 8 16 1.092555

128 1 16 2 1 1 8 64 1.2555160 1 8 10 1 1 8 40 1.220659192 1 4 36 1 1 8 32 1.143963224 1 49 2 1 1 8 64 1.251692256 0 32 2 1 1 256 4 1.447143288 0 12 36 1 1 24 8 1.531979320 0 2 160 1 1 32 10 1.545049

Tabela 5.15. Sincos métrica ipc GPU-GTX-780

N Kernel gx gy gz bx by bz ipc64 1 8 2 1 1 8 32 0.56021996 1 16 2 1 1 6 48 1.121555

128 1 4 8 1 1 8 64 1.180941160 1 25 4 1 1 8 32 1.153305192 1 48 2 1 1 8 48 1.158062224 1 1 14 8 1 1 7 0.163557256 0 2 1 128 16 4 4 1.379496288 0 18 6 3 8 2 16 1.510971512 0 40 10 1 1 16 16 1.621145

ciclo na GPU TitanX, a configuração (6, 54, 1, 4, 2, 32) para 𝑁 = 288, registrou-se o valor de1.128665. Realizando a mudança primeiramente nos grids (2, 3, 54, 4, 2, 32) e (4, 27, 3, 4, 2, 32)obtiveram-se os valores de 0.048547 e 0.048605. Quando a mudança ocorreu para as dimensõesdos blocos (6, 54, 1, 2, 4, 32), (6, 54, 1, 2, 8, 16) e (6, 54, 1, 2, 16, 8), os valores também ficarampróximos a 1.12, (1.118665, 1.098725, 1.109356), deixando claro que os grids interferem nonúmero de instruções por ciclo.

Resultados do algoritmo Sincos com a métrica achieved_occupancy

Para Cheng et al. (2014), as instruções são executadas sequencialmente dentro de cada núcleoCUDA. Quando um warp trava, o SM passa a executar outros warps elegíveis. Idealmente éimportante ter warps suficientes para manter os núcleos do dispositivo ocupado, desta forma,ocupação é a razão de warps ativos para o número máximo de warps por SM.

Para melhorar a ocupação, Cheng et al. (2014) especifica que é preciso redimensionara configuração do bloco de threads ou reajustar os recursos para permitir mais warps ativossimultaneamente e então melhorar a utilização dos recursos de computação. Contudo, parao primeiro caso de redimensionar a configuração pode gerar extremos que restringem autilização do dispositivo que são:

Page 74: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

72

Tabela 5.16. Sincos métrica achieved_occupancy GPU-TitanX

N Kernel gx gy gz bx by bz achieved_occupancy64 1 1 4 1 64 1 16 0.49671296 1 1 3 3 16 2 32 0.498097

128 0 2 2 4 16 2 32 0.494116160 0 5 5 1 128 8 1 0.494414192 1 1 6 8 1 768 1 0.674059224 1 1 49 1 16 64 1 0.915332256 1 64 8 1 1 8 16 0.996956288 1 1 3 27 128 1 8 0.991449320 1 20 5 1 1 64 16 0.993849352 1 1 242 2 1 8 32 0.983653

Tabela 5.17. Sincos métrica achieved_occupancy GPU-GTX-1070

N Kernel gx gy gz bx by bz achieved_occupancy64 1 1 2 2 2 256 2 0.49655996 1 3 1 3 2 64 8 0.498685

128 1 2 8 1 1 128 1 0.557797160 1 1 25 1 8 16 8 0.880336192 1 6 3 2 16 32 2 0.993501224 1 1 1 49 1 512 2 0.985829256 1 4 32 1 1 8 64 0.995407288 1 1 1 81 1 16 64 0.979221320 1 25 4 1 1 64 16 0.993195352 1 22 1 44 2 2 32 0.994109

Tabela 5.18. Sincos métrica achieved_occupancy GPU-GTX-780

N Kernel gx gy gz bx by bz achieved_occupancy64 1 2 2 16 2 8 4 0.841996 1 6 48 1 1 4 8 0.808754

128 1 4 64 2 1 1 32 0.789405160 1 8 4 25 2 4 4 0.790263192 1 3 384 1 32 1 1 0.778187224 0 49 1 32 2 16 1 0.776259256 0 32 4 16 4 4 2 0.772842288 0 6 27 16 1 1 32 0.77213320 0 50 16 4 8 2 2 0.771277

• Pequenos blocos de threads: poucos threads por bloco levam a limites de hardwareno número de warps por SM a serem atingidos antes que todos os recursos sejamtotalmente utilizados.

• Blocos de threads grandes: muito threads por bloco levam a menos recursos dehardware por SM disponíveis para cada thread.

Assim, os resultados podem ser visualizados nas Tabelas 5.16, 5.17 e 5.18, sendo

Page 75: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

73

que, os valores para a ocupância próximos a 1.0 são configurações que comprovam o conceitoapresentado por Cheng et al. (2014). Ainda nas Tabelas 5.16, 5.17 e 5.18, outro dadointeressante que pode ser visualizado é que há, pelo menos um valor múltiplo de 32 nos blocos.Por exemplo, para 𝑁 = 320 e 𝑁 = 352 das GPUS TitanX e GTX-1070 os blocos possuempelo menos um valor múltiplo de 32, e foram os valores que se aproximaram de 1.0, essesvalores podem mostrar uma possível tendência de configuração.

Resultados do algoritmo Sincos com a métrica sm_efficiency

A métrica sm_efficiency verifica a porcentagem de warps ativos durante a execução do código,sua diferença para a métrica occupancy é que observa o quanto de warps estão ativos nomomento, quanto mais próximo de 100% melhor é sua eficiência bem como a ocupação que ocódigo está se aplicando nos núcleos CUDA.

Tabela 5.19. Sincos métrica sm_efficiency GPU-TitanX

N Kernel gx gy gz bx by bz sm_efficiency64 1 2 16 4 8 4 1 93.02%96 1 144 1 2 2 2 8 99.63%

128 1 2 32 4 1 16 4 99.8%160 1 8 50 1 1 2 32 99.52%192 1 8 8 9 2 8 4 97.38%224 1 1 2 784 2 4 4 99.16%288 1 1296 2 1 1 8 4 99.6%320 1 2 160 10 4 2 4 99.47%352 1 1 88 44 16 2 1 99.9%

Tabela 5.20. Sincos métrica sm_efficiency GPU-GTX-1070

N Kernel gx gy gz bx by bz sm_efficiency64 1 2 4 16 2 4 4 93.81%96 1 48 1 6 8 1 4 99.62%

128 1 4 32 2 8 1 8 99.8%160 1 10 40 1 1 32 2 99.46%192 1 24 4 6 4 8 2 98.82%224 1 49 8 4 16 2 1 99.04%256 1 2 1 512 8 8 1 99.78%288 1 36 72 1 1 8 4 99.47%320 1 5 80 8 4 8 1 99.44%352 1 2 22 44 2 8 4 99.9%

Para os valores apresentados nas Tabelas 5.19, 5.20 e 5.21, todas as configuraçõesalcançaram valores superiores a 90%, vale ressaltar que esses são consideradas as melhoresconfigurações. Por exemplo, para o dispositivo GTX-1070 considerando-se 𝑁 = 256 houveram

Page 76: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

74

Tabela 5.21. Sincos métrica sm_efficiency GPU-GTX-780

N Kernel gx gy gz bx by bz sm_efficiency64 1 1 16 8 1 8 4 97.44%96 1 4 3 1 4 32 6 98.9%

128 1 32 16 1 1 4 8 98.4%160 1 80 10 1 1 32 1 99.49 %192 1 12 4 1 1 48 16 99.79%224 1 1 4 392 32 1 1 99.73%256 1 128 16 1 1 16 2 99.68 %288 1 72 18 2 2 2 16 99.81%320 1 5 160 4 16 1 2 99.85%

configurações que obtiveram valores como 68.1% para a configuração (16, 2, 2, 32, 32, 1) e73.79% para a configuração (128, 4, 4, 1, 16, 2).

Também pode ser visto que foi a única métrica que os melhores resultados foramencontrados com o kernel_1, sendo ele as interações dos dois laços mais internos transferidospara o arranjo de threads (Tabela 3.3). Os valores dos blocos muito próximos (valores entre2, 4 e 8), como exemplo as configurações (1, 2, 784, 2, 4, 4, 24, 4, 6, 4, 8, 2 e 32, 16, 1, 1, 4, 8) dosdispositivos TitanX, GTX-1070 e GTX-780, respectivamente, demonstram que pode haver umapossível tendência de configuração.

5.2.2. Experimento 2 com OpenTuner: GEMM

As seções seguintes apresentam os resultados obtidos pelo OpenTuner para o algoritmo GEMMcom as métricas gld_efficiency, gst_efficiency, inst_per_warp, ipc, achieved_occupancy esm_efficiency. Os resultados completos para este experimento podem ser visualizados norepositório do GitHub11, sendo que, todas as configurações testadas foram armazenadas emarquivos no formato .csv e os melhores resultados foram armazenados em arquivos no formato.json.

Resultados do algoritmo GEMM com a métrica gld_efficiency

A métrica gld_efficiency que verifica a taxa de transferência solicitada da memória globalpara a taxa de transferência da memória global necessária, as Tabelas 5.22, 5.23 e 5.24 expõeas melhores configurações encontradas pelo OpenTuner.

Os valores para a métrica gld_efficiency não retornaram valores satisfatórios como oalgoritmo GEMM, os maiores valores encontrados ficaram em torno de 20%. Uma possívelresposta para esses valores é o nível de exigência computacional que o algoritmo representa,bem como o kernel ter somente um laço transferido para o arranjo de threads.

11 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/tree/master/results>

Page 77: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

75

Tabela 5.22. GEMM métrica gld_efficiency GPU-TitanX

N gx gy gz bx by bz gld_efficiency64 2 4 1 1 128 4 21.68%96 6 6 1 1 128 2 21.67%

128 32 2 1 1 128 2 21.67%160 4 10 1 1 1 32 21.69%192 1 192 1 2 32 3 21.67%224 7 8 1 2 14 32 21.68%320 80 1 8 1 5 32 21.69%512 1 128 32 1 8 8 21.70%

Tabela 5.23. GEMM métrica gld_efficiency GPU-GTX-1070

N gx gy gz bx by bz gld_efficiency64 4 2 1 1 128 4 21.68%96 12 2 1 1 1 128 21.67%

128 16 2 1 1 256 2 21.67%160 2 25 1 1 256 2 21.67%192 12 3 4 1 4 64 21.67%224 196 1 4 2 2 16 21.68%320 5 4 32 20 2 4 21.69%512 16 2 8 4 8 32 21.7%

Tabela 5.24. GEMM métrica gld_efficiency GPU-GTX-780

N gx gy gz bx by bz gld_efficiency64 2 4 1 1 128 4 21.68%96 2 12 1 1 192 2 21.67%

128 4 16 1 1 128 2 21.67 %160 5 5 1 1 512 2 21.67%192 1 4 12 3 16 16 21.67%224 4 1 49 4 16 4 21.68%320 1 40 40 1 1 64 21.69%512 4 16 8 32 16 1 21.7%

Um dado interessante que pode ser encontrado no arquivo contendo todas asconfigurações geradas (GitHub12) é que por exemplo, para 𝑁 = 96 no dispositivo GTX-1070em torno de 80% dos testes retornaram o valor de 21.63%, sendo apenas 11 configurações como valor de 21.67%. Interessante também é que para o valor de 𝑁 = 512 na GPU GTX-780todas as configurações tiveram o valor de 21.7%.

Os gráficos na Figura 5.2 apresentam uma visão geral das configurações (eixo 𝑋)com os valores da métrica gld_efficiency.

Para a GPU TitanX para 𝑁 = 160 foi de 21.69%, sendo que os menores valoresficaram na faixa de 19%, essa diferença pode ser visualizada no gráfico (a) da Figura 5.2, naqual aparece 3 faixas de valores aglomerados, sendo a primeira em torno de 19%, a segunda

12 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/tree/master/results>

Page 78: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

76

(a) Espaço de busca métrica gld_efficiency TitanX

(b) Espaço de busca métrica gld_efficiency GTX-1070

(c) Espaço de busca métrica gld_efficiency GTX-780

Figura 5.2. Comparação entre os testes e os valores encontrados para a métrica gld_efficiency

faixa em torno de 20% e por último a faixa entre 21.5%, sendo esta com os maiores valores.Essa divisão fica mais nítida visualizada nos gráficos (b) e (c) que são respectivamente dosdispositivos GTX-1070 e GTX-780 para 𝑁 = 512 e 320.

Page 79: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

77

Resultados do algoritmo GEMM com a métrica gst_efficiency

Como foi feito com a métrica gld_efficiency foi realizada a execução dos testes para a métricagst_efficiency, esta retorna a porcentagem de uso da memória global em operações de store.As Tabelas 5.25, 5.26 e 5.27 trazem um demonstrativo das melhores configurações para amétrica gst_efficiency.

Tabela 5.25. GEMM métrica gst_efficiency GPU-TitanX

N gx gy gz bx by bz gst_efficiency64 16 1 1 1 8 32 12.5%96 3 4 6 2 8 8 12.5%

128 2 32 4 8 8 1 12.23%160 1 25 4 128 1 2 12.29%192 12 8 4 2 3 16 12.5%224 14 4 1 2 112 4 12.5%320 20 10 16 2 2 8 12.5%512 1 4 2048 16 2 1 12.5%

Tabela 5.26. GEMM métrica gst_efficiency GPU-GTX-1070

N gx gy gz bx by bz gst_efficiency64 2 1 4 4 16 8 12.5%96 8 2 2 36 1 8 12.5%

128 1 16 4 32 4 2 12.5%160 20 4 1 8 5 8 12.5%192 12 2 16 48 2 1 12.5%224 28 2 14 1 32 2 12.5%320 4 5 160 32 1 1 12.5%512 2 1 128 2 512 1 12.5%

Assim como a métrica gld_efficiency a métrica gst_efficiency não trouxe valoressatisfatórios, tendo como máximo a porcentagem entre 12.2% a 12.5%. Entre todos os testesrealizados os valores ficaram entre 6.69% a 12.5%, somado todas configurações testadas nostrês dispositivos, tem-se que 98% das configurações apresentaram o valor 12.5%. Assim parao algoritmo GEMM qualquer configuração que for escolhida trará um valor próximo de 12.5%.

Resultados do algoritmo GEMM com a métrica inst_per_warp

A métrica inst_per_warp representa as instruções executadas por warp em cada multiproces-sador. As Tabelas 5.28, 5.29 e 5.30 expõem as configurações e os resultados gerados pelamétrica inst_per_warp.

Esta foi a métrica que trouxe mais curiosidade para o desenvolvimento deste trabalho.Como citado nos resultados pela métrica inst_per_warp no algoritmo sincos, os valoresconsiderados bons são próximos a 100.0, contudo, os valores apresentados por esta métrica para

Page 80: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

78

Tabela 5.27. GEMM métrica gst_efficiency GPU-GTX-780

N gx gy gz bx by bz gst_efficiency64 16 1 1 16 1 16 12.5%96 1 8 3 16 24 1 12.5%

128 2 8 32 2 1 16 12.5%160 1 2 80 32 5 1 12.5%192 4 16 6 2 3 16 12.5%224 8 7 7 2 64 1 12.5%320 5 4 16 2 16 10 12.5%512 2 1 256 32 4 4 12.5%

Tabela 5.28. GEMM métrica inst_per_warp GPU-TitanX

N gx gy gz bx by bz inst_per_warp64 4 2 1 1 32 16 157.12596 4 3 1 1 32 24 155.083333

128 2 8 1 1 64 16 154.0625160 4 8 1 1 50 16 115.78125192 24 2 1 1 12 64 103.020833224 7 8 1 1 28 32 102.875320 25 4 1 1 256 4 92.69512 8 256 1 128 1 1 51.345703

Tabela 5.29. GEMM métrica inst_per_warp GPU-GTX-1070

N gx gy gz bx by bz inst_per_warp64 2 8 1 1 32 8 105.062596 6 2 1 1 64 12 155.083333

128 8 2 1 1 16 64 154.0625160 5 5 1 1 128 8 133.36192 4 12 1 1 24 32 103.020833224 14 4 1 1 32 28 102.875320 2 50 1 1 128 8 92.69512 2 128 1 1 64 16 77.691406

Tabela 5.30. GEMM métrica inst_per_warp GPU-GTX-780

N gx gy gz bx by bz inst_per_warp64 2 2 1 1 16 64 247.2596 3 4 1 1 64 12 139.75

128 2 8 1 1 128 8 139.3125160 16 2 1 1 200 4 94.40375192 6 6 1 1 32 32 103.916667224 7 7 1 1 16 64 93.857143320 4 25 1 1 32 32 75.81512 4 64 1 1 32 32 60.082031

o algoritmo GEMM foram muito alto, fazendo com que verificássemos todo o funcionamentodo OpenTuner e a verificação se o código do algoritmo GEMM estava correto.

Page 81: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

79

Após uma análise dos códigos e aprofundamento do estudo desta métrica, foidescoberto uma dependência na implementação do kernel em CUDA, na qual o valor damatriz 𝐶 depende das multiplicações da matriz 𝐴 e 𝐵, acarretando um grande número deinstruções por warp. Porém, para alguns valores de 𝑁 , por exemplo, 𝑁 = 320 em execuçõesno dispositivo GTX-780 obteve-se valores próximos a 100.

Resultados do algoritmo GEMM com a métrica ipc

Após a execução da métrica inst_per_warp foi executado os testes para a métrica ipc quemostra o número máximo de instruções executadas por ciclo de clock. Nas Tabelas 5.31, 5.32e 5.33 são apresentadas as configurações encontradas utilizando-se a métrica ipc.

Tabela 5.31. GEMM métrica ipc GPU-TitanX

N gx gy gz bx by bz ipc64 1 1 128 16 2 1 0.05810196 2 1 144 1 32 1 0.085934

128 512 1 1 1 1 32 0.087952160 1 800 1 1 1 32 0.093798192 1152 1 1 8 1 4 0.113035224 16 98 1 1 1 32 0.118226320 16 200 1 1 32 1 0.123782512 1 1 8192 2 16 1 0.101726

Tabela 5.32. GEMM métrica ipc GPU-GTX-1070

N gx gy gz bx by bz ipc64 1 16 8 1 2 16 0.09321296 24 1 6 1 1 64 0.080339

128 8 1 64 1 32 1 0.102007160 16 50 1 32 1 1 0.110495192 1 36 32 8 1 4 0.12972224 392 1 4 1 1 32 0.118445320 160 10 2 1 32 1 0.143083512 64 128 1 32 1 1 0.102246

Para a métrica ipc há uma divergência com a métrica inst_per_warp, sendo que namétrica anterior os valores extrapolaram o limite, nesta métrica os valores ficaram abaixodo esperado, sendo o maior valor 0.143083 para a configuração (160, 10, 2, 1, 32, 1) e para𝑁 = 320. Os valores testados ficaram entre 0.05 e 0.15, valores baixos.

Resultados do algoritmo GEMM com a métrica achieved_occupancy

A métrica achieved_occupancy apresenta a razão de warps ativos para o número máximo dewarps por SM. As Tabelas 5.34 e 5.35 apresentam, respectivamente, as melhores configurações

Page 82: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

80

Tabela 5.33. GEMM métrica ipc GPU-GTX-780

N gx gy gz bx by bz ipc64 128 1 1 1 32 1 0.9730696 1 1 288 1 32 1 0.97078

128 512 1 1 1 32 1 0.969908160 800 1 1 1 1 32 0.969262192 1152 1 1 4 1 8 0.966253224 1 1 1568 1 32 1 0.968673320 3200 1 1 1 1 32 0.968213512 1 1 8192 1 1 32 0.957623

para a métrica achieved_occupancy para os dispositivos TitanX e GTX-780.

Tabela 5.34. GEMM métrica occupancy GPU-TitanX

N gx gy gz bx by bz occupancy64 4 32 1 32 1 1 0.04744696 72 1 4 4 1 8 0.06805

128 512 1 1 32 1 1 0.07586160 2 16 1 1 25 32 0.382964192 3 12 1 1 16 64 0.512601224 1568 1 1 32 1 1 0.71344320 20 5 1 1 16 64 0.564393512 256 2 1 1 8 64 0.599416

Tabela 5.35. GEMM métrica occupancy GPU-GTX-780

N gx gy gz bx by bz occupancy64 64 1 2 1 2 16 0.96328396 1 72 4 1 32 1 0.965466

128 1 512 1 1 1 32 0.969834160 2 400 1 32 1 1 0.971881192 1 64 18 1 32 1 0.972941224 1 1568 1 1 1 32 0.973672320 1 64 50 32 1 1 0.974053512 1 8192 1 1 32 1 0.966274

Com a métrica achieved_occupancy e sm_efficiency ficou confirmado os baixosvalores mesmo realizando as modificações nas configurações. Foi pesquisado na literatura eum dos motivos para esses valores baixos é pelo kernel ter somente um laço transferido paraarranjos de threads fazendo com que use o mínimo da GPU. O que pode ser exemplificado apartir de 𝑁 = 320, onde há um aumento no uso dos warps e no valor de 𝑁 = 512 há umaumento significativo do uso dos warps.

Se houvesse uma continuação no aumento dos valores de 𝑁 , haveria um acréscimo nouso dos warps no dispositivo. Para exemplificarmos este aumento, foi realizado um teste por

Page 83: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

81

força-bruta na GPU TitanX com os valor de 𝑁 = 1024, a Seção 5.2.4 mostra os resultadosobtidos.

Para entender esta diferença foi desenvolvido dois diagramas de caixas que apresentao mínimo, média e os valores máximos alcançados para a métrica achieved_occupancy com𝑁 = 512 (Figura 5.3).

(a) Variação de valores na métrica achieved_occupancyTitanX

(b) Variação de valores na métrica achieved_occupancyGTX-780

Figura 5.3. Variação entre as configurações e a métrica achieved_occupancy para os dispositivosTitanX e GTX-780

Na GPU TitanX o diagrama de caixas mostra primeiramente no extremo omenor valor encontrado pela métrica utilizada, sendo este valor 0.05185, pesquisandono arquivo que contém todos os testes, a configuração que teve este desempenho foi(128, 1, 64, 4, 1, 8),com mediana em 0.429678 e com máximo em 0.599416 com a seguinteconfiguração (256, 2, 1, 1, 8, 64).

Page 84: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

82

Na GPU GTX-780 as configurações obtiveram resultados satisfatórios, sendo que omínimo encontrado no dispositivo (0.423466) é comparável a mediana encontrada pela GPUTitanX, bem como sua mediana encontra-se maior que a a melhor configuração do dispositivoTitanx. A maior taxa de ocupação encontrada foi de 0.966274. Uma possível resposta paraesta diferença de valores entre os dois dispositivos é arquitetura, sendo a GPU GTX-780arquitetura Kepler com menor número de núcleos e memória comparado a GPU Titanx.

Resultados do algoritmo GEMM com a métrica sm_efficiency

Comparável à métrica achieved_occupancy, a métrica sm_efficiency traz a porcentagemde warps ativos durante a execução do código. As Tabelas 5.36, 5.37 e 5.38 apresentam osmelhores valores para a métrica sm_efficiency.

Tabela 5.36. GEMM métrica sm_efficiency GPU-TitanX

N gx gy gz bx by bz sm_efficiency64 4 4 4 1 32 2 10.06%96 3 1 48 32 1 2 10.52%

128 1 128 2 4 1 16 10.51%160 5 10 4 2 16 4 10.23%192 32 12 1 6 4 4 10.02%224 49 4 2 32 1 4 10.65%320 10 2 32 4 5 8 11.36%512 2048 4 1 1 8 4 59.18%

Tabela 5.37. GEMM métrica sm_efficiency GPU-GTX-1070

N gx gy gz bx by bz sm_efficiency64 2 8 2 8 2 8 10.0%96 2 2 36 64 1 1 10.28%

128 4 16 4 8 1 8 10.24%160 25 8 1 1 128 1 10.14 %192 48 8 1 3 1 32 10.09%224 1 196 2 16 1 8 10.19%320 2 5 64 1 8 20 11.36%512 1024 8 1 1 2 16 59.09 %

Com a métrica sm_efficiency fica evidente que com o aumento do 𝑁 há um maioruso dos warps do dispositivo, bem como, esse aumento é explicado pela simplicidade dokernel. Essa simplicidade é demonstrado ainda mais na GPU GTX-780 que possui menornúmero de núcleos CUDA do que os outros dois dispositivos, para 𝑁 = 512 obteve-se o valorde 98.95%.

A partir deste aumento foi realizado testes por força-bruta para o algoritmo GEMMpara validar se realmente os valores são iguais para a métrica sm_efficiency. O resultado

Page 85: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

83

Tabela 5.38. GEMM métrica sm_efficiency GPU-GTX-780

N gx gy gz bx by bz sm_efficiency64 1 64 1 2 16 2 10.37 %96 1 1 24 6 4 16 10.0%

128 8 2 8 1 16 8 10.16%160 5 1 10 32 4 4 10.03%192 2 3 6 32 2 16 10.06%224 2 7 7 8 1 64 10.12%320 25 4 2 8 4 16 10.0%512 512 1 16 1 32 1 98.95 %

será apresentado na Seção 5.2.3.Para uma melhor visualização desta diferença na métrica sm_efficiency, foi criado

diagrama de caixas para 𝑁 = 512 para as três GPUS, na Figura 5.4 é mostrado os trêsdiagramas de caixa.

O primeiro diagrama de caixas Figura 5.4 (a) mostra as variações que ocorrerampara a encontrar a melhor configuração para o dispositivo Titanx. As variações ocorreramentre o mínimo (4.69%), tendo sua mediana o valor de 11.26% e o máximo entre 59.18%.Para a GPU GTX-1070 (Figura 5.4 (b)) teve variações entre o mínimo que foi encontradode 4.69% a mediana em torno de 11.22% e máximo de 59.09%. Por fim a Figura 5.4 (c)apresenta as variações que ocorreram na GPU GTX-780, havendo variações entre 9.3%, commediana em 19.15% e máximo estipulado em 98.95%.

Identificou-se uma diferença a partir dos diagramas de caixas entre os valoresencontrados entre as métricas achieved_occupancy (Figura 5.3) e a métrica sm_efficiency(Figura 5.4), sendo que na primeira o corpo do diagrama de caixas esta mais próximo dasolução ótima, já para a segunda métrica os valores ficaram próximos a solução mínima, sendoque a melhor configuração longe do "corpo"do diagrama de caixas. Com esta comparaçãofica mais evidente a dificuldade em encontrar uma configuração que utilize os recursos dodispositivo acelerador com mais eficiência.

5.2.3. Experimento 3: Experimento força-bruta GEMM

Com os resultados para o algoritmo GEMM abaixo do esperado, foi realizado uma pesquisapara verificar se havia erros nos testes na ferramenta de autotuning ou erro na implementaçãodo algoritmo na plataforma CUDA, assim desenvolveu-se um teste por força bruta para oalgoritmo GEMM para validar o funcionamento correto do OpenTuner.

Esse teste por força-bruta foi desenvolvido na linguagem Python, na qual recebiaum arquivo com todas as configurações válidas, assim ao invés de realizar os cortes atravéspor algoritmos de busca, ele realizava o teste com todas as configurações. O Código 5.3apresenta a função manipulator que realiza os testes. O restante do código está disponível do

Page 86: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

84

(a) Variação de valores na métrica sm_efficiency TitanX

(b) Variação de valores na métrica sm_efficiency GTX-1070

(c) Variações de valores na métrica sm_efficiency GTX-780

Figura 5.4. Variação entre as configurações e a métrica achieved_occupancy para os dispositivosTitanX e GTX-780

Page 87: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

85

repositório do GitHub13.� �1 . . .2 def manipulador ( ) :3 l i s t _ c o n f i g s = read _f i l e_co n f i g s ( )4 count = 15 for va lo r in l i s t _ c o n f i g s :6 print str ( count ) + " de 21231"7 p = subproces s . Popen ( ’nvprof --metrics sm_efficiency ./gemm-cuda.exe 0

’+str ( va l o r ) , s h e l l=True , stdout=subproces s . PIPE , s t d e r r=subproces s .STDOUT)

8 for l i n e in p . stdout . r e a d l i n e s ( ) :9 r e su l t ado = l i n e ,

10 r e t v a l = p . wait ( )11 s t r g = "" + l i n e12 i f s t r g . f i n d ( "Multiprocessor Activity" ) > −1:13 idx = s t r g . index ( "Multiprocessor Activity" )14 subs r tg = s t r g [ idx : ] . s p l i t ( " " )15 #p r i n t " s u b s t r g : " , s u b s r t g16 sub s t r i ng = subsr tg [ 3 ]17 subs t r i ng1 = subs t r i ng . r e p l a c e ( "%" , ’’ )18 metric_value = f loat ( subs t r i ng1 )19 print "sm_efficiency: " , metr ic_value20 va lo r = va lo r . r e p l a c e ( " " , "," ) . r e p l a c e ( " ,512,512,512" , "" )21 arquivo_csv = open( "gemm-smefficiency -512-todas -conf-funcid -titanx.csv

" , "a" )22 arquivo_csv . wr i t e ( "gx,gy,gz,bx,by,bz,funcId ,smefficiency \n" )23 arquivo_csv . wr i t e ( str ( va l o r )+","+str ( metric_value )+"\n" )24 count += 125 . . .� �

Código 5.3. Parte do código que realiza teste por força bruta para o algoritmo GEMM.

Por este método ser demorado, foi realizado somente o teste para a métricasm_efficiency com 𝑁 = 512 para as GPUs TitanX e GTX-780. Também para verificaro conceito de que quanto maior o 𝑁 maior o uso de warps foi executado para o tamanhode 𝑁 = 1024 para o dispositivo TitanX. A Tabela 5.39 apresenta as melhores configuraçõesencontradas por força-bruta para a métrica sm_efficiency.

13 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/blob/master/results/teste_todas_configuracoes/script_tuning.py>

Page 88: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

86

Tabela 5.39. Melhores configurações por força-bruta para a métrica sm_efficiency

N GTX-780 TitanXConfiguração sm_efficiency Configuração sm_efficiency

512 (4,2,1024,32,1,1) 98.87% (1,1,8192,32,1,1) 58.32%1024 — — (1,8192,4,32,1,1) 97.54%

Como esse experimento foi realizado para validar a ferramenta OpenTuner, foicomparado primeiramente os resultados da GPU GTX-780. Com o uso da ferramentaOpenTuner o valor encontrado para 𝑁 = 512 foi de 98.95% (Tabela 5.38), valor superior aoencontrado pelo método de força-bruta que foi de 98.87%, uma diferença de 0.08%. Outrodetalhe interessante são as configurações, sendo que para o teste com o OpenTuner a melhorconfiguração foi (512, 1, 16, 1, 32, 1), já para o método de força bruta foi a melhor configuraçãofoi (4, 2, 1024, 32, 1, 1), ambas configurações com mais grids por bloco, motivando a ideia quehá uma tendência de configuração.

A comparação com o dispositivo TitanX mostra que maior grids por bloco é umaboa tendência de configuração para a métrica sm_efficiency sendo que a melhor configuraçãopela execução do OpenTuner. Também para uma melhor visualização das configuraçõesexecutadas, a Tabela 5.40 mostra as configurações que obteve menores resultados juntamentecom as configurações que possuíam maiores resultados. No GitHub14 há os arquivos contendotodas as configurações executadas.

Visualizando a Tabela 5.40, pode se perceber que não há uma diferença deconfigurações entre as configurações que obtiveram menor desempenho equiparado comas que obtiveram maiores desempenho. Para as configurações que tiveram maiores valorespara a métrica sm_efficiency tanto para a GPU GTX-780 e TitanX tiveram como configuraçãode blocos os valores de (32, 1, 1), bem como mais threads por grids, mostrando que podehaver uma tendência de configuração que deve ser estudada.

Para validar a ideia que com o aumento do valor de 𝑁 para o algoritmo GEMMaumentaria o uso dos warps, assim, a Tabela 5.41 mostra as configurações e as porcentagensobtidas para a métrica sm_efficiency na GPU Titanx.

A Tabela 5.41 pode ser comparada com a Tabela 5.40 no que diz respeito aos valoresde blocos. Por exemplo, para blocos com valor de (2, 512, 1) os testes obtiveram valoresentre 5 a 6%, entretanto, para valores de blocos (32, 1, 1) obtiveram os maiores valores para𝑁 = 1024. Já na Tabela 5.36 o resultado para 𝑁 = 512 foi de 59%, afirmando que para oalgoritmo GEMM quanto maior o valor de 𝑁 há um aumento na utilização dos warps. Outrapossível tendência encontrada é que os valores de blocos interferem na métrica sm_efficiency

14 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/tree/master/results/teste_todas_configuracoes>

Page 89: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

87

Tabela 5.40. Dez Maiores e dez menores valores com base na métrica sm_efficiency

N GTX-780 TitanXConfiguração sm_efficiency Configuração sm_efficiency

512 28,1,4,16,8,4 10.23% 16,16,1,1024,1,1 5.66%512 128,2,2,16,8,4 10.21% 32,1,8,1024,1,1 5.66%512 128,4,1,16,8,4 10.21% 32,2,4,1024,1,1 5.66%512 256,1,2,16,8,4 10.24% 32,4,2,1024,1,1 5.66%512 256,2,1,16,8,4 10.21% 32,8,1,1024,1,1 5.66%512 512,1,1,16,8,4 10.21% 1,4,512,32,4,1 5.66%512 1,1,256,32,8,4 10.21% 1,8,256,32,4,1 5.67%512 1,2,128,32,8,4 10.24% 1,16,128,32,4,1 5.66%512 1,4,64,32,8,4 10.25% 1,32,64,32,4,1 5.67%512 1,8,32,32,8,4 10.28% 1,64,32,32,4,1 5.66%— — — — —512 1,1,8192,32,1,1 98.77% 1,1,8192,32,1,1 58.32%512 1,2,4096,32,1,1 98.85% 1,2,4096,32,1,1 58.01%512 1,4,2048,32,1,1 98.74% 1,4,2048,32,1,1 58.13%512 1,8,1024,32,1,1 98.76% 1,8,1024,32,1,1 57.69%512 1,16,512,32,1,1 98.74% 1,16,512,32,1,1 58.2%512 1,32,256,32,1,1 98.77% 1,32,256,32,1,1 57.66%512 1,64,128,32,1,1 98.81% 1,64,128,32,1,1 58.38%512 1,128,64,32,1,1 98.82% 1,128,64,32,1,1 58.1%512 1,256,32,32,1,1 98.73% 1,256,32,32,1,1 58.27%512 1,512,16,32,1,1 98.81% 1,512,16,32,1,1 57.53%

Tabela 5.41. Parte dos testes realizado por força-bruta para a métrica sm_efficiency

N TitanXConfiguração sm_efficiency

1024 64,16,1,2,512,1 5.66%1024 128,1,8,2,512,1 5.66%1024 128,2,4,2,512,1 5.66%1024 128,4,2,2,512,1 5.66%1024 128,8,1,2,512,1 5.66%— — —

1024 1,2,8192,2,32,1 61.2%1024 1,4,4096,2,32,1 61.19%1024 1,8,2048,2,32,1 61.26%1024 1,16,1024,2,32,1 61.19%1024 1,32,512,2,32,1 61.35%— — —

1024 2,128,128,32,1,1 97.59%1024 8,1,4096,32,1,1 97.13%1024 8,512,8,32,1,1 97.39%1024 16,4,512,32,1,1 97.17%1024 128,1,256,32,1,1 97.24%

Page 90: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

88

5.2.4. Experimento 4: Experimento força-bruta SincosTambém para validar os valores encontrados pela ferramenta OpenTuner, foi realizado o testeem força-bruta para todas as configurações válidas para o algoritmo sincos com 𝑁 = 320 e amétrica sm_efficiency.

A primeira dificuldade encontrada foi o tempo de processamento de todas asconfigurações, uma vez que para 𝑁 = 320 são geradas 33 mil configurações possíveis, ecomo seria necessário executar nos 4 kernels, houve então a quantia de 132 mil execuçõesde testes, bem a mais do que a ferramenta que encontrou a melhor configuração com 5 miltestes. Para a execução deste teste de força bruta a execução demorou em torno de 2 diaspara concluir, e com o uso da ferramenta de autotuning a melhor configuração foi encontradaem torno de 4 horas, mostrando que a ferramenta é uma solução para encontrar as melhoresconfigurações.

A Tabela 5.42 apresenta os menores valores encontrados, os valores consideradosmédios e as configurações que retornaram o melhor uso da eficiência dos warps.

Tabela 5.42. Teste por força-bruta métrica sm_efficiency

N TitanXKernel Configuração sm_efficiency

320 0 200,1,8,8,4,2 50.8%320 0 20,32,1,2,16,5 50.21%— — — —320 0 1,20,16,1,16,20 60.81%320 0 20,10,2,64,4,1 60.51%320 0 40,1,10,64,4,1 65.88%— — — —320 1 320,10,1,1,8,4 99.05%320 1 50,1,64,4,2,4 99.1%320 1 8,400,1,1,8,4 99.14%320 1 32,100,1,1,8,4 99.19%320 1 80,40,1,1,8,4 99.25%

Comparou-se os valores encontrados na força-bruta e pela ferramenta de autotuning.Utilizando a força-bruta foi encontrada a configuração (1.1600, 2, 1, 1, 8, 4) com eficiência dewarps em 99.47%. Com o uso do OpenTuner foi encontrado a configuração (2, 160, 10, 4, 2, 4)com eficiência de exatamente 99.47%, efetivando que o uso da ferramenta de autotuningencontra as melhores configurações de uma maneira rápida e correta.

Page 91: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

89

5.2.5. Resultados obtidos para Detecção e Tendências de Configu-ração

Com os testes concluídos, os arquivos gerados com as configurações foram utilizados natentativa de detectar um padrão ou uma tendência de configuração que pudesse influenciarno desempenho. No tratamento dos dados para a detecção de um possível padrão utilizou-sea linguagem de programação R.

As Figuras 5.5, 5.6 e 5.7 apresentam uma primeira análise de dados e as dificuldadesencontradas para detectar o padrão.

Figura 5.5. Valores encontrados segundo a métrica sm_efficiency

A Figura 5.5 mostra que para as configurações com a métrica sm_efficiency há 4intervalos de eficiência usando como base os grids (eixo x), esses intervalos estão entre 20%,40%, 80% e próximos a 100%. Como estamos a procura dos melhores resultados foi feito umaanálise entre os intervalos de 80% a 100%, o resultado é visto na Figura 5.6.

A partir desta análise entre intervalo de 80 - 100% foi verificado um "pico"de valoresentre 98% a 99%, sendo estes valores próximos. Desta forma, foi criado um novo conjunto dedados com somente os valores entre esse intervalos de 98 a 99%, a Figura 5.7 mostra umatabela gráfica de todas as melhores configurações, sendo os grids apresentados no eixo 𝑥,na parte superior os blocos e no eixo 𝑦 o resultado que a combinação entre grids e blocosencontrou.

A partir deste gráfico vimos a complexidade em detectar um padrão visto que osvalores de grids e blocos não seguiam um valor constante.

Para verificar essa constante, populamos um banco de dados contendo todas asexecuções, na qual a partir de queries realizamos comparações entre grids e blocos, blocoscom blocos e grids com grids, por exemplo, para comparar grids e blocos, era escolhido umaconfiguração de grid (𝑔𝑥, 𝑔𝑦, 𝑔𝑧) e esta procurava todos os resultados com esta configuraçãoe com valores de blocos diferentes. Foi necessário o uso de uma ferramenta de banco de

Page 92: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

90

Figura 5.6. Densidade de valores entre 80% a 100%

dados, visto que, havia muitas configurações, por exemplo para comparação entre grids eblocos havia um milhão cento e setenta e três mil novecentas e noventa e duas (1173992)comparações. No GitHub15 pode-se visualizar o arquivo contendo as queries e o arquivo .csvcontendo todos os resultados.

As conclusões sobre o passo de detectar padrões é visto no Capítulo 6.

5.3. Considerações FinaisEste capítulo apresentou os resultados obtidos com os experimentos que foram realizados.Primeiro foram apresentados os testes iniciais com o algoritmo soma de vetores quecontextualizou que é uma dificuldade encontrar uma configuração correta escolhendo valoresaleatoriamente, e os testes foram repetidos com o algoritmo sincos. Em seguida, foramapresentados os resultados dos testes com o uso da ferramenta de autotuning OpenTuner. Epor fim, apresentou-se as dificuldades de se encontrar um padrão ou tendência de configuração.

15 <https://github.com/jfilhoGN/tcc_cuda_opentuner_joao/tree/master/pattern_IA/testes>

Page 93: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

91

Fig

ura

5.7.

Mel

hore

sre

sulta

dos

para

am

étric

asm

_effi

cien

cy

Page 94: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Capítulo

6Conclusões

Os experimentos realizados desde os inicias com escolhas aleatórias, por força-bruta e mesmocom utilização da ferramenta de autotuning vimos que o ajuste de kernels não é uma tarefatrivial. Seja pelo tempo de execução necessário para se testar cada uma das configuraçõesválidas, seja pela variabilidade de configurações arquiteturais.

Dados os experimentos e resultados encontrados, obtivemos as seguintes conclusões:

O desenvolvedor não irá usufruir do melhor desempenho da arquitetura fazendoescolhas de dimensões aleatoriamente

Como apresentado na Seção 5.1.1 encontrar a melhor configuração de uma forma aleatórianão é a melhor solução, pois para um número de iterações pode haver inúmeras possibilidades,bem como configurações inválidas. Também escolhendo aleatoriamente o desenvolvedor nãotem a garantia que está optando pela melhor configuração, pode ser uma configuração aceitapelo hardware, porém pode não ser a mais adequada.

Utilizar do método de força bruta não é a melhor escolha

Nas seções 5.1.3, 5.2.3 e 5.2.4 a opção de buscar a melhor configuração por força bruta nãotrouxe resultados satisfatórios. Este método de busca para pequenos conjuntos de buscapode ser uma escolha ótima, contudo para buscas em grandes conjuntos se torna um métodoineficiente pelo grande custo de tempo computacional. Realizar a escolha da configuraçãopelo método de força bruta para casos que há um grande número de configurações pode serconsiderado pior que realizar a escolha aleatoriamente.

92

Page 95: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

93

Uma maneira de encontrar a melhor configuração em um tempo hábil é utilizarde ferramentas de autotuning

Ferramentas de autotuning implementam vários algoritmos de busca que diminuem o tempode processamento no processo de escolha da melhor configuração. Nas Seções 5.2.1 e 5.2.2foram apresentados os resultados encontrados com o uso da ferramenta OpenTuner, bem comoas Seções 5.2.3 e 5.2.4 validaram que a ferramenta funciona e traz resultados satisfatórios, poisnestas seções foram utilizadas técnica de força-bruta, e com o uso da ferramenta OpenTunerobteve-se valores próximos e até superiores comparado a busca com todas as configurações.

Pode haver tendências de configuração

Mesmo não encontrando um padrão, pelos resultados obtidos pelos experimentos com oalgoritmo sincos e GEMM (seções 5.2.3 e 5.2.4) os resultados apresentaram possíveis tendênciasde configuração. Por exemplo, para a métrica achieved_occupancy utilizar valores múltiplosde 32 nas configurações 𝑏𝑦, acarretava em um aumento significativo da ocupação dos warpsna execução, sendo explicado pela literatura, pois as threads são organizadas em grupos de32 warps.

Outra tendência encontrada é para a métrica sm_efficiency sendo que os melhoresdesempenhos ocorreram com grids maiores e blocos com valores menores, bem como para amétrica inst_per_warp o código deve ser desenvolvido sem blocos de código condicionais.

Detecção de Padrão

Neste trabalho, não conseguimos detectar um padrão de configuração, contudo, realizamosvários testes e coletamos as seguintes conclusões por não termos encontrado um possívelpadrão:

• Um dos algoritmos não obteve resultados satisfatórios para que pudéssemos utilizar nostestes para encontrar padrão. Para trabalhos futuros, é necessário um maior número dealgoritmos para se haver maiores combinações e assim achar possíveis padrões;

• O tempo para a execução dos testes, sobre saltou o tempo estipulado para este trabalhode conclusão de curso, tendo testes que passavam em torno de uma semana paraconcluir.

• Com a grande quantidade de configurações (chegando a 1 milhão de testes) os scriptsdesenvolvidos para encontrar um possível padrão paravam de funcionar ou haviasobrecarga de memória. Para trabalhos futuros deve-se utilizar um conjunto de dadosmenor ou procurar ferramentas que consigam trabalhar com grandes conjuntos dedados.

Page 96: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

94

6.1. Trabalhos FuturosA partir dos resultados obtidos por este trabalho, a principal contribuição é criar mecanismosque facilite o desenvolvimento de algoritmos para dispositivos aceleradores (GPU).

O uso do OpenTuner se mostrou eficiente para a descoberta da melhor configuração.Embora tenha-se testado algumas métodos para tentar encontrar um padrão de dimensõesque melhorassem o desempenho, na análise de dados como Regressão Linear e Análise deComponentes Principais, não conseguimos encontrar ainda um padrão. Acredita-se que talvezos benchmarks mesmo tendo a característica necessária para os testes, algumas dimensões delaços aninhados, talvez não apresentem uma intensidade operacional adequada ou suficiente.

Como trabalhos futuros, pretende-se testar mais benchmarks e continuar a inves-tigação para encontrar um padrão. Se um padrão for encontrado tem-se também o de-senvolvimento de um passo para uma ferramenta LLVM PoLLy que seja capaz de detectarregiões paralelizáveis sobre laços de repetições e aplicar a essas regiões ajustes, otimizações etransformações que favoreçam a paralelização e transforme o código em kernels.

Page 97: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

Referências

ANSEL, Jason; KAMIL, Shoaib; VEERAMACHANENI, Kalyan; RAGAN-KELLEY,Jonathan; BOSBOOM, Jeffrey; O’REILLY, Una-May; AMARASINGHE, Saman. Opentuner:An extensible framework for program autotuning. In: International Conference on ParallelArchitectures and Compilation Techniques. Edmonton, Canada: [s.n.], 2014. Disponível em:<http://groups.csail.mit.edu/commit/papers/2014/ansel-pact14-opentuner.pdf>.

BENABDERRAHMANE, Mohamed-Walid; POUCHET, Louis-Noël; COHEN, Albert;BASTOUL, Cédric. The polyhedral model is more widely applicable than you think. In:Proceedings of the 19th Joint European Conference on Theory and Practice of Software,International Conference on Compiler Construction. Berlin, Heidelberg: Springer-Verlag,2010. (CC’10/ETAPS’10), p. 283–303. ISBN 3-642-11969-7, 978-3-642-11969-9. Disponívelem: <http://dx.doi.org/10.1007/978-3-642-11970-5\_16>.

BRODTKORB, Andre R.; DYKEN, Christopher; HAGEN, Trond R.; HJELMERVIK, Jon M.;STORAASLI, Olaf O. State-of-the-art in heterogeneous computing. Sci. Program., IOS Press,Amsterdam, The Netherlands, The Netherlands, v. 18, n. 1, p. 1–33, jan. 2010. ISSN 1058-9244.Disponível em: <http://dx.doi.org/10.1155/2010/540159>.

CHENG, J.; GROSSMAN, M.; MCKERCHER, T. Professional CUDA C Programming.Wiley, 2014. (EBL-Schweitzer). ISBN 9781118739327. Disponível em: <https://books.google.com.br/books?id=\\_Z7rnAEACAAJ>.

CONWAY, Pat; KALYANASUNDHARAM, Nathan; DONLEY, Gregg; LEPAK, Kevin;HUGHES, Bill. Cache hierarchy and memory subsystem of the amd opteron processor. IEEEMicro, IEEE Computer Society Press, Los Alamitos, CA, USA, v. 30, n. 2, p. 16–29, mar.2010. ISSN 0272-1732. Disponível em: <http://dx.doi.org/10.1109/MM.2010.31>.

COOK, Shane. CUDA Programming: A Developer’s Guide to Parallel Computing withGPUs. 1st. ed. San Francisco, CA, USA: Morgan Kaufmann Publishers Inc., 2013. ISBN9780124159334, 9780124159884.

FLYNN, Michael J. Some computer organizations and their effectiveness. IEEE Trans.Comput., IEEE Computer Society, Washington, DC, USA, v. 21, n. 9, p. 948–960, set. 1972.ISSN 0018-9340. Disponível em: <http://dx.doi.org/10.1109/TC.1972.5009071>.

GASTER, Benedict; HOWES, Lee; KAELI, David R.; MISTRY, Perhaad; SCHAA, Dana.Heterogeneous Computing with OpenCL. 1st. ed. San Francisco, CA, USA: Morgan KaufmannPublishers Inc., 2011. ISBN 0123877660, 9780123877666.

GREER, Bruce; HENRY, Greg. High performance software on intel pentium pro processors ormicro-ops to teraflops. In: Proceedings of the 1997 ACM/IEEE Conference on Supercomputing.

95

Page 98: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

96

New York, NY, USA: ACM, 1997. (SC ’97), p. 1–13. ISBN 0-89791-985-8. Disponível em:<http://doi.acm.org/10.1145/509593.509639>.

GROSSER, Tobias; GROESSLINGER, Armin; LENGAUER, Christian. POLLY - PerformingPolyhedral Optimizations On A Low-level Intermediate Representation. Parallel ProcessingLetters, v. 22, n. 04, p. 1250010, dec 2012. ISSN 0129-6264. Disponível em: <http://www.worldscientific.com/doi/abs/10.1142/S0129626412500107>.

GROSSER, Tobias; ZHENG, Hongbin; ALOOR, Raghesh; SIMBÜRGER, Andreas; GRÖS-SLINGER, Armin; POUCHET, Louis-Noël. Polly - polyhedral optimization in llvm. In:Proceedings of the First International Workshop on Polyhedral Compilation Techniques (IM-PACT). [s.n.], 2011. v. 2011. Disponível em: <http://perso.ens-lyon.fr/christophe.alias/impact2011/impact-07.pdf>.

INTEL. The Intel® Xeon Phi™ 5110P coprocessor. 2013. Disponível em: <http://www.intel.com.br/content/www/br/pt/processors/xeon/xeon-phi-detail.html>.

INTEL. What is Code Modernization? 2015. [Online; posted by Michel P. at 08-July-2015].Disponível em: <https://software.intel.com/en-us/articles/what-is-code-modernization>.

KENNEDY, James; EBERHART, Russell. Particle swarm optimization. 1995.

KIRK, David B.; HWU, Wen mei W. Programming Massively Parallel Processors: AHands-on Approach. 1. ed. Morgan Kaufmann, 2010. Paperback. ISBN 0123814723. Disponí-vel em: <http://www.amazon.com/exec/obidos/redirect?tag=citeulike07-20&path=ASIN/0123814723>.

MIKUSHIN, D.; LIKHOGRUD, N.; ZHANG, E.Z.; BERGSTROM, C. KernelGen – TheDesign and Implementation of a Next Generation Compiler Platform for AcceleratingNumerical Models on GPUs. In: Parallel Distributed Processing Symposium Workshops(IPDPSW), 2014 IEEE International. [S.l.: s.n.], 2014. p. 1011–1020.

MIKUSHIN, Dmitry; LIKHOGRUD, Nikolay; ZHANG, Eddy Zheng. KERNELGEN - thedesign and implementation of a next generation compiler platform for accelerating numericalmodels on GPUs. [S.l.], 2013. 1 p.

NICKOLLS, John; DALLY, William J. The gpu computing era. IEEE Micro, IEEE ComputerSociety Press, Los Alamitos, CA, USA, v. 30, n. 2, p. 56–69, mar. 2010. ISSN 0272-1732.Disponível em: <http://dx.doi.org/10.1109/MM.2010.41>.

NVIDIA. Fermi Compute Architecture Whitepaper. [S.l.], 2009.

NVIDIA. NVIDIA CUDA C Programming Best Practices Guide. [S.l.], 2009.

NVIDIA. Kepler GK110 Whitepaper. NVIDIA, 2012. Disponível em: <http://www.nvidia.com/content/PDF/kepler/NVIDIA-Kepler-GK110-Architecture-Whitepaper.pdf>.

NVIDIA. Maxwell Compatibility Guide for CUDA Applications. [S.l.], 2014. DA-07172-0, n.February.

NVIDIA. CUDA C Best Practices Guide. [S.l.], 2015. Version 7.5. Disponível em: <http://docs.nvidia.com/cuda/cuda-c-best-practices-guide>.

Page 99: AJUSTENASDIMENSÕESDE KERNELS PARA ...repositorio.roca.utfpr.edu.br/jspui/bitstream/1/... · de Curso 2, do Curso de Bacharelado em Ciência da Computação do Departamento Acadêmico

97

NVIDIA. NVIDIA Nsight Visual Studio Edition - Instruction Statistics. [S.l.], 2015.

NVIDIA. Fermi Compute Architecture Whitepaper. [S.l.], 2016. Disponível em: <https://images.nvidia.com/content/pdf/tesla/whitepaper/pascal-architecture-whitepaper.pdf>.

NVIDIA. CUDA Toolkit Documentation. 2017. <http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#axzz4eG4mZje9>. Acessado: 14-04-2017.

POUCHET, Louis-Noël; BONDUGULA, Uday; YUKI, Tomofumi. PolyBench/C the Polyhe-dral Benchmark suite. 2012. Disponível em: <http://web.cse.ohio-state.edu/~pouchet/software/polybench/>.

RAHMAN, R. Intel Xeon Phi Coprocessor Architecture and Tools: The Guide for ApplicationDevelopers. Apress, 2013. (The expert’s voice in microprocessors). ISBN 9781430259275.Disponível em: <https://books.google.com.br/books?id=wZ-9AAAAQBAJ>.

ROBINSON, J.; RAHMAT-SAMII, Y. Particle swarm optimization in electromagnetics.IEEE Transactions on Antennas and Propagation, v. 52, n. 2, p. 397–407, Feb 2004. ISSN0018-926X.

RUSSELL, Stuart J.; NORVIG, Peter. Artificial Intelligence: A Modern Approach. 2. ed.[S.l.]: Pearson Education, 2003. ISBN 0137903952.

STORN, Rainer. On the usage of differential evolution for function optimization. In: inNAFIPS’96. [S.l.]: IEEE, 1996. p. 519–523.

STORN, Rainer; PRICE, Kenneth. Differential evolution – a simple and efficient heuristic forglobal optimization over continuous spaces. Journal of Global Optimization, v. 11, n. 4, p. 341–359, 1997. ISSN 1573-2916. Disponível em: <http://dx.doi.org/10.1023/A:1008202821328>.

STRINGHINI, D.; GONCALVES, R.; GOLDMAN, A. Capítulo 7: Introdução à computaçãoheterogênea. In: Luiz Carlos Albini, Alberto Ferreira de Souza, Renata Galante, RobertoCesar Junior, Aurora Pozo. (Org.). XXXI Jornadas de Atualização em Informática. Curitiba,Paraná, Brazil: Sociedade Brasileira de Computação (SBC), 2012. v. 21, p. 262–309. Disponívelem: <http://www.lbd.dcc.ufmg.br/bdbcomp/servlet/Trabalho?id=12580>.

SUTTER, Herb; LARUS, James. Software and the concurrency revolution. Queue, ACM,New York, NY, USA, v. 3, n. 7, p. 54–62, set. 2005. ISSN 1542-7730. Disponível em:<http://doi.acm.org/10.1145/1095408.1095421>.

VERDOOLAEGE, Sven; JUEGA, Juan Carlos; COHEN, Albert; GóMEZ, José Ignacio;TENLLADO, Christian; CATTHOOR, Francky. Polyhedral Parallel Code Generation forCUDA. ACM Trans. Archit. Code Optim., ACM, New York, NY, USA, v. 9, n. 4, p. 54:1–54:23, jan. 2013. ISSN 1544-3566. Disponível em: <http://dl.acm.org/citation.cfm?doid=2400682.2400713>.

WHALEY, R. Clint; DONGARRA, Jack. Automatically Tuned Linear Algebra Software. In:Ninth SIAM Conference on Parallel Processing for Scientific Computing. [S.l.: s.n.], 1999.CD-ROM Proceedings.

WILLIAMS, Samuel Webb. Auto-tuning Performance on Multicore Computers. Tese (Douto-rado), Berkeley, CA, USA, 2008. AAI3353349.