SlideShare uma empresa Scribd logo
1 de 83
Baixar para ler offline
CENTRO UNIVERSITÁRIO UNIVATES
CENTRO DE CIÊNCIAS EXATAS E TECNOLÓGICAS
CURSO DE ENGENHARIA DE CONTROLE E AUTOMAÇÃO
AUGUSTO LIMBERGER LENZ
COMPUTAÇÃO PARALELA COM ARQUITETURA DE
PROCESSAMENTO GRÁFICO CUDA APLICADA A UM
CODIFICADOR DE VÍDEO H.264
Lajeado
2012
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
AUGUSTO LIMBERGER LENZ
COMPUTAÇÃO PARALELA COM ARQUITETURA DE
PROCESSAMENTO GRÁFICO CUDA APLICADA A UM
CODIFICADOR DE VÍDEO H.264
Trabalho de Conclusão de Curso apresentado ao
Centro de Ciências Exatas e Tecnológicas do Centro
Universitário UNIVATES, como parte dos requisitos
para a obtenção do título de bacharel em Engenharia de
Controle e Automação.
Área de concentração: Computação paralela
ORIENTADOR: Ronaldo Hüsemann
Lajeado
2012
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
AUGUSTO LIMBERGER LENZ
COMPUTAÇÃO PARALELA COM ARQUITETURA DE
PROCESSAMENTO GRÁFICO CUDA APLICADA A UM
CODIFICADOR DE VÍDEO H.264
Este trabalho foi julgado adequado para a obtenção do
título de bacharel em Engenharia de Controle e
Automação do CETEC e aprovado em sua forma final
pelo Orientador e pela Banca Examinadora.
Orientador: ____________________________________
Prof. Ronaldo Hüsemann, UNIVATES
Doutor pelo PPGEE/UFRGS – Porto Alegre, Brasil
Banca Examinadora:
Prof. Marcelo de Gomensoro Malheiros, UNIVATES
Mestre pela FEEC/UNICAMP – Campinas, Brasil
Prof. Maglan Cristiano Diemer, UNIVATES
Mestre pelo PPGCA/UNISINOS – São Leopoldo, Brasil
Coordenador do curso de Engenharia de Controle e Automação
_______________________________
Prof. Rodrigo Wolff Porto
Lajeado, Junho de 2012.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
Dedico este trabalho ao meu pai, Edu, e a minha mãe, Ivone, por acreditarem na
importância da educação.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
AGRADECIMENTOS
À minha família, pelo apoio, incentivo e compreensão nos momentos difíceis, no
transcorrer da realização desse trabalho e demais atividades da graduação.
Ao professor Ronaldo Hüsemann, pela sua orientação, pelas oportunidades de
trabalhar em projetos de pesquisa e pela amizade cultivada ao longo desse período.
Aos colegas do Laboratório de Engenharia Aplicada: Anderson Giacomolli, Diego
Schwingel e Marco Gobbi pelas contribuições no desenvolvimento desse trabalho.
Aos colegas de curso, pela amizade e companhia durante o decorrer desta jornada.
À Luisa por todo o amor, carinho e compreensão.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
RESUMO
Este trabalho investiga a utilização de processadores gráficos (GPUs) como coprocessadores
em arquiteturas de computadores no contexto da codificação de vídeo. O objetivo específico é
implementar módulos do codificador H.264 em tecnologia CUDA, presente nas placas de
vídeo da empresa NVIDIA. Dessa forma, algoritmos paralelizáveis são executados na GPU de
forma a acelerar a codificação e aliviar a carga da CPU principal. O primeiro estudo de caso
foi a implementação do módulo computacional, situado no codificador intraquadro, que foi
integrado ao software de referência para validação e testes. Os resultados obtidos apontam um
ganho de cerca de 3,9 vezes no tempo de execução deste módulo para vídeos de alta
definição. No segundo estudo de caso foi abordado o codificador interquadros através da
estimação de movimento. Um algoritmo de busca adequado à arquitetura paralela em questão
foi proposto e implementado, além da implementação do cálculo de SAD. Os resultados
obtidos na estimação de movimento apontam para um aumento na velocidade de execução em
torno de 5,7 vezes para vídeos de alta definição.
Palavras-chaves: Codificação de Vídeo, Computação Paralela, GPGPU, CUDA.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
ABSTRACT
This work investigates the use of graphical processing units (GPUs) as co-processors for
computer architectures in the context of video encoding. The specific goal is to implement
modules of the H.264 encoder in CUDA, present in NVIDIA video cards. Thus, parallelizable
algorithms have been implemented on the GPU to accelerate the encoding and reduce the load
of the main CPU. The first case study was the implementation of computational module,
situated in the intra-frame encoder, that was integrated into the reference software for
validation and testing. The results show a speedup of 3.9 times in the execution of
computational module for high-definition video. In the second case study, the inter-frame
encoder was approached through motion estimation. A search algorithm suitable for parallel
architecture was proposed and implemented, in addition to the SAD calculation. The results
show a speedup of 5.7 times in the execution for high-definition videos.
Keywords: Video Coding, Parallel Computing, GPGPU, CUDA.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
SUMÁRIO
1 INTRODUÇÃO...................................................................................................................15
2 UNIDADE DE PROCESSAMENTO GRÁFICO............................................................19
2.1 Histórico das GPUs......................................................................................................19
2.1.1 Primeira geração...................................................................................................20
2.1.2 Segunda geração....................................................................................................20
2.1.3 Terceira Geração...................................................................................................21
2.1.4 Quarta geração......................................................................................................21
2.1.5 Quinta geração......................................................................................................22
2.2 Pipeline gráfico tradicional.........................................................................................22
2.3 Processamento de propósito geral em GPU...............................................................23
2.4 Visão Geral da CUDA..................................................................................................23
2.5 Arquitetura de hardware............................................................................................25
2.6 Modelo de programação..............................................................................................27
2.6.1 Função Kernel.......................................................................................................27
2.6.2 Hierarquia de threads...........................................................................................28
2.6.3 Hierarquia de memória........................................................................................29
2.7 Detalhamento dos espaços de memória......................................................................31
2.7.1 Registradores e memória local.............................................................................31
2.7.2 Memória compartilhada.......................................................................................31
2.7.3 Memória global.....................................................................................................32
2.7.4 Memória de textura e superfície..........................................................................33
2.7.5 Memória de constantes.........................................................................................34
3 CODIFICAÇÃO DE VÍDEO.............................................................................................35
3.1 Vídeo digital..................................................................................................................35
3.2 Compressão de vídeo...................................................................................................36
3.3 Introdução ao H.264....................................................................................................37
3.4 Descrição do codec H.264............................................................................................37
3.4.1 Predição intraquadro............................................................................................38
3.4.2 Transformadas diretas e inversas........................................................................40
3.4.2.1 Transformada discreta de cossenos..................................................................41
3.4.2.2 Transformada de Hadamard............................................................................44
3.4.3 Quantização...........................................................................................................45
3.4.4 Estimativa de movimento.....................................................................................48
3.4.4.1 Algoritmos de busca...........................................................................................50
3.4.4.2 Critérios de similaridade...................................................................................53
3.4.5 Compensação de movimento................................................................................54
3.5 Trabalhos relacionados............................................................................................54
4 DESCRIÇÃO DO SISTEMA DESENVOLVIDO...........................................................56
4.1 Codificação intraquadro..........................................................................................57
4.2 Algoritmos de computação intra................................................................................57
4.2.1 Implementação da DCT direta e inversa............................................................59
4.2.2 Implementação da Transformada de Hadamard..............................................59
4.2.3 Implementação da Quantização..........................................................................60
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
4.3 Codificação interquadros........................................................................................61
4.3.1 Algorítimo de busca proposto..............................................................................61
4.3.2 Implementação da estimação de movimento......................................................62
5 RESULTADOS PRÁTICOS..............................................................................................66
5.1 Integração com o software de referência...................................................................66
5.2 Avaliação dos resultados no módulo computacional intra.......................................67
5.3 Avaliação do algoritmo de busca proposto................................................................69
5.4 Avaliação dos resultados da estimativa de movimento em GPU.............................71
5.5 GPU profiling...............................................................................................................75
6 CONCLUSÃO.....................................................................................................................77
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
LISTA DE FIGURAS
Figura 1 Shader tradicional x shader unificado, adaptado de (IKEDA, 2011).................24
Figura 2 Escalabilidade da arquitetura CUDA, adaptada de (NVIDIA, 2011a)..............25
Figura 3 Cenários comuns de branch divergence, adaptada de (HAN;
ABDELRAHMAN , 2011).....................................................................................26
Figura 4 Organização das threads, adaptada de (NVIDIA, 2011a)...................................29
Figura 5 Fluxo típico de uma aplicação CUDA....................................................................30
Figura 6 Padrões de acesso coalescido (CONRAD, 2010)...................................................32
Figura 7 Acesso não coalescido (CONRAD, 2010)...............................................................33
Figura 8 Estrutura do codificador H.264 (REDIESS, 2006)...............................................38
Figura 9 Modos de predição para blocos 16x16 de luminância. (AGOSTINI, 2007).......39
Figura 10 Modos de predição para blocos 4x4 de luminância (AGOSTINI, 2007)..........40
Figura 11 Bloco de entrada (a) e resultado da DCT (b) (RICHARDSON, 2003).............42
Figura 12 Macroblocos de crominância e luminância com componentes DC destacados
(MAJOLO, 2010)....................................................................................................44
Figura 13 Quadros consecutivos de vídeo (RICHARDSON, 2003)....................................49
Figura 14 Na esquerda, o resíduo sem estimativa de movimento. Na direita, o resíduo
com estimativa de movimento (RICHARDSON, 2003)......................................49
Figura 15 Predição interquadro (DINIZ, 2009)...................................................................50
Figura 16 Algoritmo de busca completa (PORTO, 2012)...................................................51
Figura 17 Large Diamond Search (LDS) e Small Diamond Search (SDS) (PORTO, 2008)
..................................................................................................................................52
Figura 18 Algoritmo de busca logarítmica (RICHARDSON, 2002)..................................52
Figura 19 Processo de codificação intraquadro, adaptada de (DINIZ, 2009)...................57
Figura 20 Etapas do módulo computacional........................................................................58
Figura 21 Arquitetura proposta para módulo computacional usando GPUs NVIDIA
(HUSEMANN et al., 2011b). ................................................................................58
Figura 22 Relacionamento das threads com os componentes DC......................................60
Figura 23 Padrão de busca do algoritmo proposto..............................................................62
Figura 24 Procedimento de redução usado no cálculo de SAD, adaptado de (NVIDIA,
2012).........................................................................................................................64
Figura 25 Distribuição do tempo entre as etapas.................................................................76
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
LISTA DE CÓDIGOS
Listagem 1 Declaração e chamada de um kernel.................................................................28
Listagem 2 Protótipo da função intrínseca usad..................................................................63
Listagem 3 Primeira etapa da redução.................................................................................64
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
LISTA DE TABELAS
Tabela 1 Evolução da distribuição dos estágios entre CPU e GPU....................................23
Tabela 2 Características dos espaços de memória na arquitetura CUDA séries G80 e
G200.........................................................................................................................30
Tabela 3 Passos de quantização.............................................................................................46
Tabela 4 Valores de PF para cada posição...........................................................................47
Tabela 5 Fator de multiplicação............................................................................................47
Tabela 6 Complexidade dos módulos do codificador H.264...............................................56
Tabela 7 Principais características das duas placas utilizadas...........................................66
Tabela 8 Comparação dos tempos de processamento para vídeos 4CIF...........................68
Tabela 9 Comparação dos tempos de processamento vídeo HD........................................68
Tabela 10 Avaliação do algoritmo de busca proposto para 3 Mbps..................................70
Tabela 11 Avaliação do algoritmo de busca proposto para 4 Mbps..................................70
Tabela 12 Avaliação do algoritmo de busca proposto para 5 Mbps..................................71
Tabela 13 Comparação dos desempenho em QCIF.............................................................72
Tabela 14 Comparação dos desempenho em CIF................................................................73
Tabela 15 Comparação dos desempenho em 4CIF..............................................................73
Tabela 16 Comparação dos desempenho em 720p...............................................................74
Tabela 17 Comparação dos desempenho em 1080p.............................................................75
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
LISTA DE ABREVIATURAS
AMD Advanced Micro Devices
ANSI American National Standards Institute
API Application Programming Interface
AVC Advanced Video Coding
CAD Computer Aided Design
CIF Common Intermediate Format
CPU Central Unit Processing
CUDA Compute Unified Device Architecture
DC Direct Current
DCT Discrete Cosine Transform
DSP Digital Signal Processor
DVD Digital Versatile Disc
FS Full Search
GLSL OpenGL Shading Language
GPU Graphics Processing Unit
GPGPU General Purpose GPU
HD High Definition
HLSL High Level Shader Language
IBM International Business Machines
IEC International Electro-technical Commission
ISO International Organization for Standardization
ITU-T International Telecommunication Union – Telecommunication
Standardization Sector
JSVM Joint Scalable Video Model
JVT Joint Video Team
LDS Large Diamond Search
LS Logarithmic Search
MAE Mean Square Error
MSE Mean Square Error
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
MC Compensação de movimento
ME Estimativa de movimento
MF Multiplication Factor
MPEG Motion Picture Experts Group
PC Personal Computer
PCIe Peripheral Component Interconnect Express
PF Post-Scaling Factor
PGC Professional Graphics Controller
QP Quantization Parameter
RAM Random Access Memory
RGB Red Green Blue
SAD Sum of Absolute Differences
SD Standard Definition
SDS Small Diamond Search
SGI Silicon Graphics International
SIMD Single Instruction, Multiple Data
SIMT Single-Instruction, Multiple-Thread
SLI Scalable Link Interface
SM Streaming Multiprocessor
SP Scalar Processors
SSE Streaming SIMD Extensions
SVC Scalable Video Coding
VRAM Video Random Access Memory
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
15
1 INTRODUÇÃO
A capacidade de armazenar e transportar vídeo em formato digital tornou as aplicações
que fazem uso desta tecnologia parte do cotidiano das pessoas. Atualmente, o vídeo digital
está presente em televisores, Digital Versatile Discs (DVDs), videoconferência e sistemas de
telemedicina (FUJITSU, 2010).
A codificação de vídeo é a técnica essencial que possibilita a utilização de vídeos de
forma eficiente. Essa técnica permite a transformação do sinal de vídeo em uma representação
comprimida, onde são eliminadas redundâncias, e, com isso reduzir a largura de banda
necessária para transportar o vídeo ou o espaço em disco necessário para armazená-lo. O
processo de decodificação recupera o sinal de vídeo original ou uma aproximação deste, de
forma que possa ser visualizado em sua forma original (RICHARDSON, 2003).
A necessidade por técnicas de compressão de vídeo pode ser ilustrada pelo seguinte
cenário. Considerando-se, por exemplo, um vídeo com standard definition (SD), que possui
720 x 480 pixeis, e utilizando o sistema de três cores primárias red green blue (RGB), com 8
bits de representação para cada cor e 30 quadros por segundo, seriam necessários
aproximadamente 30 MB para armazenar apenas um segundo de vídeo.
Dada esta necessidade, surgiram diversas formas de realizar a codificação. Pode-se
dizer que a base das técnicas empregadas na maioria dos codificadores atuais foi estabelecida
na norma H.261 da International Telecommunication Union – Telecommunication
Standardization Sector (ITU-T) definida em 1989, da qual pode-se destacar como algoritmos
principais a estimativa de movimento, transformada discreta de cosseno (DCT), quantização
linear e codificação de entropia (GHANBARI, 2003).
Posteriormente, foi desenvolvido o padrão MPEG-2 pelo Motion Picture Experts
Group (MPEG) e também adotado pela ITU-T, como uma norma conjunta das duas entidades
e passando a ser chamado H.262/MPEG-2, que tornou-se extremamente popular. O MPEG-2
foi empregado, por exemplo, nos DVDs e em diversos sistemas de televisão digital
(MAJOLO, 2010). Este padrão continuou popular ao longo dos anos, sendo largamente
empregado ainda nos dias de hoje.
A criação de técnicas inovadoras, como a codificação de cenas sintéticas e naturais em
um modelo de codificação baseado em objetos independentes e a possibilidade de codificação
realizada sobre objetos não necessariamente retangulares, resultou no padrão MPEG-4
(RICHARDSON, 2003).
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
16
As entidades MPEG e ITU-T uniram novamente esforços para desenvolver um novo
padrão de codificação. Este grupo de trabalho é conhecido como Joint Video Team (JVT).
Como resultado surgiu o padrão chamado de Advanced Video Coding (AVC), publicado
como a recomendação H.264 da ITU-T e como a parte dez do MPEG-4 (AGOSTINI, 2007).
A elaboração do codec H.264 foi feita com o aumento da eficiência da compressão
sendo o principal objetivo, resultando em aumentos significativos nas taxas de compressão.
No entanto, esta evolução levou inevitavelmente ao aumento dos requisitos de processamento
para os dispositivos codificadores e decodificadores (RICHARDSON, 2003).
Os algoritmos empregados para codificação de vídeo requerem computação intensa,
tornando necessárias técnicas computacionais sofisticadas e o uso de arquiteturas dedicadas
que tornem possível a execução destes algoritmos em tempo real. Dentre as soluções que vêm
sendo adotadas pode-se destacar a utilização de arquiteturas do tipo Single Instruction,
Multiple Data (SIMD), Digital Signal Processor (DSP) e o desenvolvimento de
coprocessadores dedicados em hardware (GREENE; TULJAPURKAR, 2007).
Uma alternativa recentemente explorada para aumento de desempenho de algoritmos é
a utilização de unidades de processamento gráfico, ou Graphics Processing Unit (GPU), como
plataformas para processamento de propósito geral. Este conceito, que é conhecido como
General Purpose GPU (GPGPU), torna possível explorar o poder de processamento das placas
aceleradoras de vídeo em aplicações que não necessariamente façam uso de recursos gráficos
(CHEUNG et al., 2010).
As GPUs possuem uma arquitetura altamente paralela, capaz de executar a mesma
operação em um grande número de elementos ao mesmo tempo. Esta forma de organização é
apropriada ao seu objetivo original - processamento de gráficos em três dimensões (3D), mas
também pode ser empregada na implementação de algoritmos úteis em diversos outros
campos (IKEDA, 2011).
Nos últimos anos, foram criadas tecnologias para adequar a GPU ao processamento de
propósito geral e facilitar o desenvolvimento de programas que possam fazer uso deste
recurso. Um exemplo notável é a arquitetura de computação paralela da NVIDIA denominada
Compute Unified Device Architecture (CUDA) (NVIDIA, 2011d). Outros exemplos são:
Advanced Micro Devices (AMD) Stream (AMD, 2011), o framework OpenCL (KHRONOS,
2011) e a application programming interface (API) Microsoft Direct Compute
(MICROSOFT, 2009).
Acredita-se que a utilização de placas de vídeo como ferramenta de auxílio na tarefa
de codificação de vídeo seja de grande interesse, dada a variedade de aplicações com vídeo
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
17
digital e a grande disseminação destes dispositivos em computadores pessoais. Portanto, este
trabalho se propõe a investigar a utilização de GPUs, presentes nas placas de vídeo
compatíveis com a tecnologia NVIDIA CUDA, como coprocessadores da Central Unit
Processing (CPU) no contexto da codificação de vídeo. Mais especificamente, o objetivo é
implementar módulos do codificador H.264 que possuam algoritmos paralelizáveis na GPU,
de forma a acelerar a codificação e aliviar a carga da CPU principal.
Desta forma, foi explorada a implementação de referência do codificador H.264 de
forma a identificar pontos onde a utilização da arquitetura CUDA seja vantajosa. A partir
dessa análise e da revisão da literatura, foram definidos dois módulos do codificador a serem
trabalhados como estudos de caso: módulo computacional e módulo de estimação de
movimento.
O primeiro estudo de caso aborda o codificador intraquadros através da
implementação dos algoritmos do módulo computacional: transformada discreta de cossenos
direta e inversa, transformada de Hadamard direta e inversa, quantização e quantização
inversa. Já o segundo estudo de caso aborda a codificação interquadros através da
implementação de algoritmos da estimação de movimento: algoritmo de busca e cálculo de
similaridade.
Para tornar possível a validação e a avaliação dos módulos desenvolvidos foi realizada
a integração com o codificador de referência do padrão H.264. Dessa forma, o software de
referência serviu como base de comparação em termos do desempenho alcançado e a
validação dos resultados será obtida através da comparação dos vídeos comprimidos gerados
pelo software original com os vídeos obtidos pela versão paralela.
A fim de embasar o desenvolvimento deste trabalho foram pesquisados trabalhos
relacionados. Sprandlin et al. (2009) por exemplo analisou a viabilidade de implementar um
codificador MPEG-2 na arquitetura CUDA. Chan et al. (2009), Cheung et al. (2010) e Huang,
Shen e Wu (2009) por sua vez exploraram diferentes abordagens para acelerar a execução dos
algoritmos de estimativa de movimento também utilizando CUDA. Monteiro et al. (2011)
realizaram a implementação do algoritmo de busca completa em CUDA, obtendo ganhos de
velocidade de 600 vezes. Os trabalhos estudados apontam que a utilização da tecnologia
CUDA pode trazer avanços à área de codificação de vídeo, de forma a tornar viável a
execução em tempo real de complexas técnicas de codificação em vídeos de alta resolução.
O texto desta monografia foi organizado da seguinte forma. O capítulo 2 apresenta
uma revisão de literatura acerca da evolução da arquitetura das GPUs que culminou no
conceito de GPGPU. O capítulo 3 define os conceitos relacionados à codificação de vídeo, as
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
18
características básicas do padrão H.264 e uma descrição dos trabalhos relacionados estudados.
O capítulo 4 formaliza a proposta de trabalho que guiou a execução das atividades. O capítulo
5 apresenta os estudos de caso realizados. Por fim, o capítulo 6 apresenta as conclusões
obtidas e aponta possíveis trabalhos futuros.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
19
2 UNIDADE DE PROCESSAMENTO GRÁFICO
A Unidade de Processamento Gráfico é um processador dedicado à aceleração de
aplicações gráficas. A arquitetura das GPUs difere substancialmente das tradicionais CPUs,
pois direcionam-se a necessidades específicas, como processamento de dados 3D com ponto
flutuante. Sua organização interna torna possível uma intensidade aritmética muito maior,
através da execução de diversas operações iguais em dados independentes (OWNEW et al.,
2005).
Essas características surgiram da necessidade de processar um grande número de
pixeis para gerar uma imagem a ser exibida. Como cada pixel é independente dos demais é
possível calcular os valores de vários pixeis simultaneamente. Esta arquitetura paralela
possibilita portanto a execução de um grande número de operações por unidade de tempo.
2.1 Histórico das GPUs
A ideia de se utilizar processadores especificamente para as tarefas relacionadas a
vídeo remonta ao ano de 1984 quando a International Business Machines (IBM) lançou a
primeira placa de vídeo com microprocessador próprio (Intel 8088) de forma a amenizar a
carga da CPU principal. Nesta época, o processador era empregado apenas para gerar os
sinais de vídeo, a fim de possibilitar melhores taxas de atualização da tela. Essa solução,
conhecida como Professional Graphics Controller (PGC), era destinada a custosos sistemas de
Computer Aided Design (CAD) e não se disseminou para o mercado de massa (DUKE;
WALL, 1985).
Em 1986, a Texas Instruments lançou o processador TMS34010. Este chip, além de
possuir uma memória dedicada para vídeo, chamada de Video Random Access Memory
(VRAM) e suporte a display, foi um dos primeiros a apresentar um conjunto de instruções
voltado ao processamento gráfico (GUTTAG et al., 1988).
Entretanto, no final dos anos 80 surgiram as primeiras placas de vídeo compatíveis
com a arquitetura IBM-PC (Personal Computer), que possuíam implementações em hardware
das primitivas gráficas de duas dimensões (2D) e, por isso, tornaram-se conhecidas como
placas aceleradoras 2D (CROW, 2004).
No início dos anos 90, a Silicon Graphics International (SGI), que era líder no
mercado de gráficos 3D, criou a API OpenGL, que posteriormente tornou-se um padrão
mantido por diversas entidades. O surgimento da OpenGL trouxe uma forma uniforme de
acesso às diferentes placas gráficas e deixou aos fabricantes a responsabilidade de
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
20
desenvolver device drivers para os seus produtos. Posteriormente, a empresa Microsoft lançou
o conjunto de APIs DirectX, que inclui a API Direct3D que tornou-se grande competidora da
OpenGL.
A possibilidade de escrever software utilizando uma API de alto nível compatível com
uma grande diversidade de placas de vídeo teve um forte impacto no mercado para aplicativos
gráficos (CROW, 2004).
No início da década de 90 começavam a se tornar comuns aplicativos com gráficos 3D
que faziam uso do poder de processamento da CPU, criando uma demanda crescente por
aceleração 3D em hardware. Por volta de 1995, surgiram os primeiros produtos a implementar
essa ideia: S3 ViRGE, ATI Rage, Matrox Mystique e 3dfx Voodoo. O passo seguinte à
aceleração 3D foi o surgimento das GPUs, que ocorreu por volta de 1998, acrescentando
processamento gráfico 3D ao hardware. No entanto, nesse período o processamento gráfico
ainda era realizado por funções fixas definidas no projeto da GPU. A partir desse ponto, a
evolução pode ser definida em cinco gerações (IKEDA, 2011).
2.1.1 Primeira geração
No final da década de 90, haviam três grandes empresas no segmento: NVIDIA, ATI e
3Dfx (com seus respectivos produtos, RIVA TNT2 - NV5, Rage 128 e Voodoo3). Nos
dispositivos dessa geração não havia processamento na placa além da rasterização,
texturização e geração dos sinais para o monitor. A rasterização consiste na conversão de
representações vetoriais de objetos 3D em uma representação matricial, também conhecida
como raster. Já a texturização é responsável pela aplicação de uma textura às faces de um
objeto tridimensional. A imagem 3D é sintetizada por um conjunto de polígonos (comumente
triângulos), resultantes da projeção para um espaço bidimensional (AZEVEDO, 2003).
2.1.2 Segunda geração
Em 1999, o lançamento da GeForce 256 (NV10) pela empresa NVIDIA, destacou-se
pela introdução do pipeline gráfico, tornando a GPU responsável pela transformação e
iluminação dos polígonos, especificados em coordenadas de mundo. Neste período a ATI
lançou a família de produtos Radeon R100 com a tecnologia HyperZ, que permitia evitar
cálculos desnecessários em pixeis não visíveis na projeção final.
O pipeline gráfico é um modelo conceitual composto por estágios que aplicam uma
série de algoritmos aos dados processados por uma GPU. Os dados de entrada são um
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
21
conjunto de vértices e os respectivos atributos. Após a execução de todos os estágios do
pipeline, obtém-se a representação de uma imagem a ser exibida na tela. A adoção dessa
arquitetura possibilitou um grande avanço nos jogos e aplicações gráficas em tempo real, pois
boa parte das tarefas que antes eram feitas pela CPU foram levadas para o hardware da GPU.
Esta arquitetura permitia uma certa flexibilidade ao desenvolvedor, que podia configurar os
módulos da GPU (IKEDA, 2011).
A empresa 3DFX, por sua vez, lançou a tecnologia Scalable Link Interface (SLI), que
permitia a conexão e utilização em paralelo de duas placas de vídeo. Posteriormente, a 3DFX
foi adquirida pela NVIDIA, que passou a utilizar esta tecnologia em sua linha de produtos.
Neste mesmo período, ATI e NVIDIA tinham produtos com características semelhantes
dando início a uma concorrência acirrada (IKEDA, 2011).
2.1.3 Terceira Geração
Em 2001, a NVIDIA lançou a primeira GPU programável – GeForce 3 (NV20), que
competiu diretamente com a Radeon 8500 (R200) lançada pela ATI. A introdução das
técnicas de pixel shading e vertex shading foi a grande evolução desta geração (VIANA,
2009).
O pixel shading torna possível desenvolver programas capazes de manipular os pixeis
após a rasterização, de forma a criar efeitos na imagem, como por exemplo, rugosidade ou
desfoque. Já vertex shading possibilita a criação de programas capazes de manipular a
estrutura dos vértices do modelo tridimensional (ou seja, antes de rasterização), para otimizar
os modelos 3D ou alterar o modelo dinamicamente. Os programas desenvolvidos com essas
duas técnicas são conhecidos como shaders. Ambas as técnicas são utilizadas a fim de obter
maior realismo nas imagens sem sobrecarregar a CPU principal, pois os shaders são
executados inteiramente pela GPU (ST-LAURENT, 2004).
A capacidade de processamento desta geração era limitada, sendo necessário utilizar a
linguagem de montagem (assembly) da GPU. Entretanto, a partir desta fase a GPU começou a
ser encarada com um hardware vetorial programável (VIANA, 2009).
2.1.4 Quarta geração
A quarta geração introduziu o tratamento de variáveis de ponto flutuante e uma maior
flexibilidade na utilização de dados de textura. Nesse período, com início por volta de 2003, a
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
22
concorrência foi intensa com o lançamento da série FX (NV30) e GeForce 6 pela NVIDIA e
da série R300 e X1 pela ATI.
Este foi um momento importante na evolução das placas de vídeo, devido a ser a
primeira vez na história em que foi possível desenvolver, ainda que precariamente, aplicativos
de propósito geral sobre tecnologias de GPU (NVIDIA, 2009).
2.1.5 Quinta geração
O ponto marcante das placas dessa geração são as arquiteturas elaboradas para
explorar a computação paralela de propósito geral em GPUs. Pode-se dizer, portanto, que
somente a partir de meados de 2006 que a computação paralela em hardware gráfico tornou-
se de grande interesse no mercado, indo além da comunidade científica (IKEDA, 2011). O
conceito de desenvolvimento de programas de propósito geral para GPUs é um dos focos
deste trabalho e, portanto, será detalhado a partir da Subseção 2.3.
2.2 Pipeline gráfico tradicional
O processo executado por todo o pipeline pode ser dividido em duas etapas principais:
processamento de geometria e renderização. A primeira etapa transforma as coordenadas dos
objetos de três dimensões em representações de duas dimensões, apropriadas à exibição. A
segunda etapa preenche a área entre as coordenadas 2D com pixeis que representam a
superfície dos objetos. O estágio de geometria ainda pode ser subdividido em: transformações
e iluminação (CROW, 2004).
Inicialmente, apenas a renderização era implementada em hardware, por ser uma
operação simples e repetitiva, e as outras operações eram executadas pela CPU. Com a
evolução no desenvolvimento das GPUs, cada vez mais tarefas foram alocadas às placas de
vídeo, a fim de diminuir a carga da CPU (NVIDIA, 1999).
A ideia do pipeline é fazer com que cada um desses módulos opere em paralelo, ao
invés de tratar um pixel de cada vez. Nas placas de vídeo modernas, o pipeline completo é
replicado diversas vezes, de forma a obter maior vazão no processamento. Ao longo dos anos,
mais etapas do pipeline foram sendo trazidas da CPU para a GPU, chegando ao cenário atual,
onde apenas a lógica da aplicação e as computações da cena são executadas pela CPU
principal. A Tabela 1 lista os estágios do pipeline gráfico e a evolução da distribuição dos
mesmos entre CPU e GPU.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
23
As características do pipeline delinearam a arquitetura das GPUs. O fato de todos os
pixeis necessitarem passar pelos mesmos módulos de execução levou as GPUs a adotarem
arquiteturas paralelas.
Tabela 1 Evolução da distribuição dos estágios entre CPU e GPU.
Estágio 1996 1997 1998 1999
Lógica da aplicação CPU CPU CPU CPU
Computações da cena CPU CPU CPU CPU
Transformações CPU CPU CPU GPU
Iluminação CPU CPU CPU GPU
Criação dos triângulos CPU Processador gráfico Processador gráfico GPU
Renderização Processador gráfico Processador gráfico Processador gráfico GPU
Fonte: NVIDIA, 1999.
2.3 Processamento de propósito geral em GPU
O uso da GPU para processamento de propósito geral começou com a utilização de
linguagens de shading, como Direct3D High Level Shader Language (HLSL) e OpenGL
Shading Language (GLSL). Dessa forma, aplicações em diversas áreas foram aceleradas, no
entanto exigindo que todos os algoritmos fossem adaptados para trabalhar com dados
expressos em termos de vértices e texturas. Nas primeiras soluções, haviam outras limitações,
como a impossibilidade de leituras e escritas em posições aleatórias da memória (NVIDIA,
2009).
O uso de chips e APIs gráficas neste contexto revelou um grande potencial na
aceleração de algoritmos que possuam uma estrutura passível de paralelização, fazendo uso de
hardware padrão presente em um grande número de computadores. O surgimento deste novo
segmento resultou na criação de arquiteturas que tornam as GPUs mais apropriadas ao
processamento geral e ao desvinculamento de seus ambientes de desenvolvimento das APIs
gráficas tradicionais. A primeira arquitetura de GPGPU, também chamada de computação
para GPU, foi criada pela empresa NVIDIA e será detalhada a seguir.
2.4 Visão Geral da CUDA
CUDA é a arquitetura de computação paralela de propósito geral que faz uso da
capacidade de processamento presente nas GPUs da NVIDIA. A arquitetura CUDA provê um
modelo de programação escalável baseado em três conceitos centrais: uma hierarquia de
grupos de threads, memória compartilhada entre as threads e barreiras de sincronização.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
24
Esses conceitos são expostos ao desenvolvedor como um conjunto de extensões à linguagem
C (NVIDIA, 2011a).
A arquitetura CUDA definiu duas alterações principais na organização das GPUs: a
unificação dos shaders (vertex e pixel shaders) e a criação de memória compartilhada. O
componente resultante da união dos shaders é chamado stream processor (SP). Essas
alterações transformaram as GPUs em dispositivos adequados ao processamento de propósito
geral (HUANG; SHEN; WU, 2009).
A Figura 1 ilustra a arquitetura unificada dos shaders em contraste aos shaders
tradicionais. A unificação dos shaders transformou as unidades especializadas em
processamento de vértices ou pixeis, por exemplo, em unidades de computação genérica
interconectadas por um escalonador dinâmico que divide a carga de processamento entre as
diversas unidades que compõe a GPU. Dessa forma, a utilização dos recursos de hardware foi
flexibilizada.
Figura 1 Shader tradicional x shader unificado, adaptado de (IKEDA, 2011).
Os grupos de threads são escalonados para execução em um dos núcleos,
sequencialmente ou simultaneamente, sem que seja necessário explicitar em qual núcleo o
bloco será alocado. Desta forma, um mesmo programa poderá ser executado em GPUs com
diferentes quantidade de núcleos e, ainda assim, fará uso de todo o poder de computação
disponível.
A Figura 2 ilustra a execução de um mesmo programa em duas placas de vídeo, a da
esquerda possui uma GPU com dois núcleos e a da direita com quatro núcleos. O programa
em questão foi parametrizado para execução com oito blocos de threads. No primeiro caso,
cada núcleo fica responsável pela execução de quatro blocos. Já no segundo caso, os oito
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
25
blocos são divididos entre os quatro núcleos disponíveis. Esse escalonamento é realizado
internamente pela GPU e não é determinado pelo código da aplicação. Dessa forma, a
arquitetura provê um ambiente escalável para a execução dos programas.
Figura 2 Escalabilidade da arquitetura CUDA, adaptada de (NVIDIA, 2011a).
A arquitetura CUDA já sofreu algumas alterações desde a sua concepção inicial.
Algumas características foram sendo implementadas ao longo do tempo, a fim de aprimorar o
desempenho das GPUs. Portanto, diferentes placas podem conter um conjunto de
características diferentes. A fim de identificar as características presentes em um determinado
dispositivo, todas as placas são categorizadas em compute capabilities identificados por um
versionamento numérico. Os manuais da NVIDIA apresentam as características do hardware
de acordo com essa numeração. Por exemplo, um determinada funcionalidade pode estar
presente apenas nos dispositivos de compute capability 1.2. Se a funcionalidade for descrita
para o compute capability 2.x, significa que todos as placas com versão 2 suportam-na,
independentemente do outro algarismo.
2.5 Arquitetura de hardware
As placas de vídeo compatíveis com a tecnologia CUDA possuem um conjunto
escalável de multiprocessadores, que são chamados streaming multiprocessors (SMs). Os
SMs são compostos por uma série de processadores escalares (scalar processors – SP), uma
unidade de instrução multi thread e memória compartilhada. Os blocos de threads criados
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
26
pelo kernel são escalonados para execução em SMs com capacidade ociosa. As threads dentro
de um mesmo bloco são executadas concorrentemente, pois cada thread é mapeada em um
SP, com seus próprios registradores. A NVIDIA chamou essa arquitetura de Single-
Instruction, Multiple-Thread (SIMT) (NVIDIA, 2011a).
O escalonador de threads separa-as em grupos, chamados warps. A cada ciclo de
instrução um warp é selecionado para execução, então a mesma instrução é executada em
todas as threads ativas neste warp (NVIDIA, 2011c). Apesar de todas as threads começaram
a execução no mesmo ponto do código, há a possibilidade de que haja ramificação na
execução. Neste caso, nem todas as threads estarão ativas no mesmo momento, resultando na
serialização da execução. Portanto, para que seja alcançada eficiência máxima na execução
paralela das threads é necessário que não hajam ramificações no fluxo de execução (branch
divergence) dentro de um mesmo warp (HAN; ABDELRAHMAN , 2011).
A Figura 3 apresenta três casos típicos onde ocorre a divergência no fluxo de
execução. Na situação (a), o incremento executado dentro do bloco condicional faz com que
os SPs destinados às threads que não executam o incremento fiquem inativos por alguns
ciclos. O cenário (b) pode ser interpretado como duas instruções condicionais na sequência,
com as mesmas implicações do exemplo anterior. No terceiro caso, o número de iterações
executadas no laço pode diferir para cada thread. A diferença no número de iterações do laço
para cada thread resultará que os SPs alocados para as threads com menor número de
iterações ficarão inativos, enquanto os outros SPs executam as últimas iterações para as outras
threads do mesmo warp (HAN; ABDELRAHMAN , 2011).
Figura 3 Cenários comuns de branch divergence, adaptada de (HAN; ABDELRAHMAN , 2011).
Esta arquitetura criada pela NVIDIA é similar às arquiteturas SIMD presentes em
diversas CPUs, no entanto, existem diferenças importantes (REN et al. 2010). Nas
arquiteturas SIMD, diversos elementos de dados são salvos em um registrador. A largura dos
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
27
registradores, que determina o nível de paralelismo em nível de instrução, é exposta ao
software. Na arquitetura SIMT, por outro lado, o paralelismo se dá pela execução de diversas
threads que podem executar trechos de código distintos (NVIDIA, 2011c).
O comportamento específico da arquitetura SIMT pode ser ignorado pelo programador
a fim de obter-se uma implementação meramente funcional de determinado algoritmo, mas
através da adequação da implementação às características próprias do hardware (GPU) é
possível obter maiores ganhos de desempenho. Analogamente, nas arquiteturas tradicionais é
possível ignorar a largura das linhas de cache e, ainda assim, obter implementações
funcionais. No entanto, quando almeja-se obter picos de desempenho essa informação precisa
ser considerada (NVIDIA, 2011c).
2.6 Modelo de programação
O modelo de programação do CUDA permite que o programador crie um grande
número de threads que executarão código escalar, ou seja, cada thread analisada isoladamente
contém código que será executado sequencialmente, sem nenhum nível de paralelismo. O
modelo de programação criado pela NVIDIA possibilita aos desenvolvedores criar aplicações
paralelas com certo grau de facilidade, mesmo aqueles que não possuem grande familiaridade
com arquiteturas paralelas (BAKHODA et al., 2009).
As características do modelo de programação são expostas ao programador através de
uma extensão da linguagem de programação ANSI C (American National Standards
Institute). Os três conceitos chave desse modelo são descritos nas subseções seguintes: kernel,
hierarquia de threads e hierarquia de memória.
2.6.1 Função Kernel
A extensão da linguagem C criada pela NVIDIA possibilita a criação de funções que
serão executadas na GPU. Para tanto, existem três palavras-chave: __global__, __device__ e
__host__. A primeira delas específica uma função que será executada na GPU, mas será
chamada da CPU. Uma função com esta característica é chamada de kernel e cabe ao
programador especificar quantas vezes esta função deve ser executada paralelamente. Para
tanto, na chamada do kernel é definido o tamanho do grid, ou seja, a quantidade de blocos de
threads (NVIDIA, 2011). Na Listagem 1, a linha um contém o protótipo com a declaração de
um kernel e a linha dois a chamada do kernel, com a especificação dos parâmetros de
execução.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
28
1 __global__ kernel_function(char *buffer);
2 kernel_function<<<dimGrid,dimBlock,0,stream>>>(buffer);
Listagem 1 Declaração e chamada de um kernel.
A palavra-chave __device__, por outro lado, declara uma função que será executada
pela GPU e poderá ser invocada somente por código executado na própria GPU. Já a palavra-
chave __host__ declara funções convencionais, ou seja, que são chamadas e executadas pela
CPU. __host__ é o qualificador padrão na declaração de funções, portanto, não precisa estar
explícito no protótipo da função.
2.6.2 Hierarquia de threads
A organização das threads se dá na forma de blocos com uma, duas ou três dimensões.
Esse arranjo torna simples a execução de cálculos em elementos de vetores, matrizes ou
volumes. A identificação da thread que está sendo executada é possível através dos índices
que identificam a posição da thread dentro do bloco. Os índices são disponibilizados ao
programador através da variável tridimensional threadIdx que contém três campos de inteiros
sem sinal: x, y, z.
Os blocos contém grupos de threads que são organizados em um grid, que também
pode ter até três dimensões. O tamanho do grid é determinado a partir da quantidade de dados
a serem manipulados ou pela quantidade de processadores.
Os blocos são identificados dentro do grid de mesma forma que as threads dentro de
um bloco. Para tanto, existe a variável blockIdx, do tipo uint3. Já o tamanho dos blocos, ou
seja, a quantidade de threads pode ser obtido através da variável blockDim.
As variáveis threadIdx, blockIdx e blockDim são chamadas built-in, ou seja, elas são
automaticamente acessíveis dentro do kernel, mesmo sem terem sido explicitamente
declaradas.
A execução dos blocos de threads poderá ocorrer em qualquer ordem, serialmente ou
paralelamente. Portanto, a operação executada em um bloco não pode depender de resultados
obtidos em outros blocos. Essa característica possibilita a escalabilidade do código, de forma
a utilizar diferentes quantidades de núcleos de processamento disponíveis (NVIDIA, 2011a).
As threads que residem no mesmo bloco são executadas no mesmo SM podendo
cooperar entre si através do compartilhamento de dados (pela memória compartilhada) e
sincronização da execução com funções intrínsecas que servem como barreiras na execução,
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
29
de forma que a execução prossiga apenas quando todas as threads tenham finalizado a
execução de uma determinada sequência de instruções.
AFigura 4 ilustra a forma de organização hierárquica das threads.
Figura 4 Organização das threads, adaptada de (NVIDIA, 2011a)
2.6.3 Hierarquia de memória
CUDA expõe seu modelo de memória, que é composto por diferentes espaços de
memória, tornando necessário ao desenvolvedor conhecer a arquitetura e definir onde cada
conjunto de dados da aplicação deve residir. A correta utilização das diferentes memórias
presentes na placa de vídeo, geralmente, tem implicação direta no desempenho do aplicativo.
A Tabela 2 apresenta um visão geral das memórias disponíveis na arquitetura CUDA.
Pode-se observar que as memórias mais abundantes possuem uma latência elevada por
estarem localizadas fora do chip. A quinta coluna da tabela define que as memórias de
constantes e de texturas possuem acesso somente de leitura, ou seja, é possível escrever nestas
memórias apenas através de código executado na CPU. A subseção seguinte apresenta um
detalhamento de cada uma dessas memórias.
O fluxo dos dados na aplicação geralmente segue o seguinte padrão: inicialmente os
dados são copiados da memória RAM (random access memory) do computador (host) para a
memória global da GPU (device), através do barramento Peripheral Component Interconnect
Express (PCIe). Após essa cópia os dados já estão acessíveis às threads, no entanto, é comum
realizar a transferência da memória global para a memória compartilhada de um SM, de forma
a minimizar a quantidade de acessos à memória global. Dessa forma, a memória
compartilhada é utilizada como um cache entre a memória global e o aplicativo, para reduzir
os efeitos da alta latência no acesso a memória global.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
30
Tabela 2 Características dos espaços de memória na arquitetura CUDA séries G80 e G200.
Memória Localização Tamanho Latência
Somente
leitura
Escopo
Registradores SM
até 64 kB por
SM
~ 0 ciclos não thread
Local
Placa de
vídeo
depende da
global
400 – 600
ciclos
não thread
Compartilhada SM1
16 kB por SM >= 4 ciclos não
Todas as
threads em
um bloco
Global
Placa de
vídeo
até 1024 MB
400 – 600
ciclos
não
Todas as
threads + host
Constante
Placa de
vídeo2 64 kB 0 – 600 ciclos sim
Todas as
threads + host
Textura
Placa de
vídeo3
depende da
global
0 – 600 ciclos sim
Todas as
threads + host
Fonte: Adaptado de NVIDIA, 2011b e Conrad, 2010.
Após esta etapa, as threads manipulam os dados que estão na memória compartilhada,
utilizando os registradores para armazenar variáveis de controle e resultados intermediários.
Ao final do processamento, cada thread escreve o resultado da sua execução na memória
global, a fim de tornar acessível ao host os resultados obtidos. Por fim, o host copia os
resultados que estão na memória global de volta para a memória do computador.
Figura 5 Fluxo típico de uma aplicação CUDA.
1
Esta memória possui cache nos dispositivos 2.x.
2
Esta memória possui cache em todos os dispositivos.
3
Esta memória possui cache em todos os dispositivos.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
31
2.7 Detalhamento dos espaços de memória
A seguir serão apresentados os detalhes relevantes de cada memória.
2.7.1 Registradores e memória local
Os registradores são utilizados para armazenar as variáveis automáticas (também
chamadas de variáveis locais). Se não houver espaço suficiente, o compilador alocará as
variáveis na memória local. Dessa forma, estruturas ou vetores (automáticos) grandes
possivelmente serão alocados na memória local. Como a memória local está localizada fora
do chip e não possui cache (em dispositivos 1.x), apresenta tempo acesso elevado (NVIDIA,
2011b). A memória local é apenas uma abstração sobre a memória global, com escopo
limitado a cada thread (IKEDA, 2011). Portanto, a quantidade e o tamanho das variáveis
automáticas podem influenciar diretamente o desempenho do aplicativo.
2.7.2 Memória compartilhada
A memória compartilhada está localizada dentro de cada multiprocessador, por isso,
possui latência cerca de cem vezes menor do que a memória global ou local, porém o tamanho
total desta memória é reduzido (NVIDIA, 2011b). A memória compartilhada pode ser
utilizada como uma memória cache explicitamente gerenciada, ou seja, cabe ao programador
utilizar esse recurso para minimizar a quantidade de acessos a memória global.
A memória compartilhada é organizada em bancos, ou seja, módulos que podem ser
acessados simultaneamente, a fim de obter uma alta largura de banda. Essa arquitetura
permite que diversas requisições, que acessem endereços localizados em diferentes bancos,
possam ser atendidas ao mesmo tempo. Por outro lado, se uma requisição de acesso a
memória contiver acessos em endereços localizados no mesmo banco haverá um conflito de
acesso. Nessa situação, os acessos serão separados em requisições consecutivas separadas
para que não contenham nenhum conflito (NVIDIA, 2011a).
A ocorrência de conflitos se dá quando mais de uma thread pertencente ao mesmo
half-warp4
solicitam acesso a posições de memória que localizam-se em um mesmo banco.
Há uma exceção no caso de todas as threads de um half-warp executarem uma leitura no
mesmo endereço, neste caso o conteúdo lido é disponibilizado para todas as threads através
de um broadcast. Em dispositivos com compute capability 2.x há também a possibilidade de
4
Half-warp é um grupo de threads, com metade do tamanho de um warp. Em dispositivos com compute
capability 1.x, o half-warp é menor unidade escalonada pelo SM. Já em dispositivos com compute capability 2.x
a menor unidade escalonada é o próprio warp.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
32
multicast, onde o conteúdo lido é disponibilizado para um grupo de threads, mas não
necessariamente para todas (NVIDIA, 2011b).
2.7.3 Memória global
A memória global está localizada na placa de vídeo, no entanto, não sendo integrada
ao chip da GPU, possui alta latência no acesso. Esta memória pode ser acessada através de
transações de 32, 64 ou 128 bytes, alinhadas. Isto é, o endereço do primeiro elemento
manipulado precisa ser um múltiplo do tamanho do segmento (NVIDIA, 2011a).
As requisições de acesso à memória global efetuadas por um half-warp (em
dispositivos com compute capability 1.x) ou por um warp (em dispositivos com compute
capability 2.x) são combinadas resultando na menor quantidade de transações possível, que
obedeça as regras de alinhamento impostas pela arquitetura de hardware (NVIDIA, 2011b).
As regras que definem o agrupamento dos acessos à memória global em transações
variam entre dispositivos com diferentes compute capabilities. Inicialmente, a arquitetura da
GPU impunha restrições mais severas no padrão de acesso que resultava na combinação de
vários acessos em uma transação. Entretanto, as placas de vídeo mais recentes, que possuem
compute capability 2.x, apresentam avanços nesse quesito.
A Figura 6 ilustra padrões de acesso que permitem o acesso coalescido, ou seja, o
acesso a várias posições de memória em apenas uma transação. Desta forma, os efeitos da
latência de acesso são diluídos. A figura (a) exemplifica o acesso coalescido a variáveis float
de quatro bytes. A figura (b) ilustra o acesso coalescido por um warp divergente, ou seja,
neste caso nem todas as threads acessam as respectivas variáveis.
Figura 6 Padrões de acesso coalescido (CONRAD, 2010).
A Figura 7, por outro lado, exemplifica padrões de acesso que não possibilitam o
acesso coalescido. A figura (a) possui um padrão de acesso não sequencial, ou seja, as
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
33
threads não acessam as suas respectivas posições. Já a figura (b) apresenta um padrão de
acesso sequencial. No entanto, o acesso é desalinhado o que impossibilita o coalescing.
Figura 7 Acesso não coalescido (CONRAD, 2010).
Uma característica dos dispositivos com compute capability 2.x que pode amenizar o
impacto da alta latência no acesso a memória global é a presença de dois níveis de cache
(cache L1 e L2) entre o SM e a memória global.
O cache L1 é composto de linhas de 128 bytes que mapeiam segmentos alinhados na
memória global. Já o cache L2 é composto por linhas de 32 bytes. O tamanho das linhas
determinam o tamanho da transação que será usada para acessar os dados através do cache.
Em certas circunstâncias pode ser vantajoso utilizar apenas o cache L2, por exemplo,
quando os acessos são dispersos na memória a utilização de cache com linhas mais estreitas
resulta numa menor quantidade de leituras ou escritas desnecessárias. Por esse motivo, o
compilador possui um parâmetro que permite definir se os acessos a memória global
utilizarão os caches L1 e L2 ou apenas o L2 (NVIDIA, 2011a).
2.7.4 Memória de textura e superfície
A memória de textura ou superfície está localizada na memória da placa de vídeo e
possui cache otimizado para acesso a dados que apresentem localidade espacial em duas
dimensões, ou seja, dados localizados em posições próximas. Além disso, esse espaço de
memória é projetado de forma a obter fluxos de leitura com latência constante. Dessa forma,
uma leitura do cache reduz a largura de banda demandada, mas a latência se mantém
constante (NVIDIA, 2011a).
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
34
Quando um warp necessita de um dado que está presente no cache há um ganho
significativo no tempo de leitura, caso o dado não esteja disponível no cache o tempo de
acesso será o mesmo de uma leitura na memória global convencional.
A memória de textura pode ser escrita a partir do host, mas do ponto de vista da GPU
é uma memória somente de leitura.
2.7.5 Memória de constantes
A memória de constantes está localizada no dispositivo e possui memória cache.
Possui acesso somente de leitura pela GPU. Além de ser usada explicitamente, em
dispositivos com compute capability 2.x esta memória pode ser utilizada pelo compilador
através de instruções específicas (NVIDIA, 2011a).
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
35
3 CODIFICAÇÃO DE VÍDEO
Um codificador de vídeo transforma o vídeo de sua forma original em uma
representação comprimida, de forma a permitir uma utilização mais eficiente de recursos
como largura de banda (nos sistemas de comunicação) e espaço (nos sistemas de
armazenamento). A utilização do vídeo codificado requer um decodificador, que é o sistema
capaz de realizar a conversão inversa, a fim de obter o vídeo na sua forma natural. O par
codificador/decodificador é o que se chama codec (RICHARDSON, 2010).
3.1 Vídeo digital
O vídeo digital baseia-se na utilização de dados amostrados temporalmente e
espacialmente. A partir da amostragem, obtém-se uma matriz retangular com valores que
representam a informação visual que é composta por três componentes, devido às
características fisiológicas do sistema visual humano (GONZALEZ, 2000).
A forma de representação das três componentes é chamado espaço de cores. Existem
diversos espaços empregados em diferentes aplicações. Os monitores de vídeo utilizam o
RGB, baseado nas componentes vermelha, verde e azul. Já os sistemas de televisão e os
codificadores de vídeo utilizam o YCbCr, que define a luminância (Y), a crominância azul
(Cb) e a crominância vermelha (Cr) (SHI; SUN, 2008).
A utilização do espaço de cores YCbCr associado com a subamostragem das
crominâncias é realizada através de padrões de amostragem bem estabelecidos, como 4:4:4,
4:2:2 e 4:2:0. Na amostragem 4:4:4 as crominâncias são mantidas intactas, portanto, todos os
pixeis possuem uma amostra de cada componente (Y, Cb e Cr). No caso 4:2:2, a amostragem
das crominâncias possui a metade da resolução no sentido horizontal, ou seja, para cada
quatro amostras de luminância existem duas amostras de cada crominância. Por fim, o
formato 4:2:0 reduz a resolução tanto horizontalmente quanto verticalmente, ou seja, para
cada quatro amostras de luminância é utilizada apenas uma amostra de cada crominância,
obtendo 50% menos bits na representação, se comparado com o formato 4:4:4
(RICHARDSON, 2003).
A subamostragem é amplamente utilizada nos codificadores atuais, devido à redução
do espaço de informação ocupado por esta técnica. Por exemplo, um vídeo em formato
YCbCr 4:2:0 obtém uma taxa de compressão de 50% em relação a um vídeo em RGB ou
YCbCr 4:4:4 com perdas de qualidade pouco significativas (AGOSTINI, 2007).
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
36
3.2 Compressão de vídeo
As técnicas de compressão com perdas são amplamente utilizadas nos codificadores
de vídeo atuais, de forma a explorar as limitações do sistema de visão humano. Além disso, o
olho humano possui sensibilidade diferenciada em relação a diferentes componentes ou
características da imagem (GONZALEZ, 2000).
Entretanto, a representação digital de vídeos apresenta uma enorme quantidade de
dados redundantes que possibilita a utilização de técnicas de codificação preditiva sem perdas.
Os altos níveis de compactação obtidos pelos codecs atuais são possíveis com a combinação
destas técnicas (com e sem perdas) (DINIZ, 2009).
Um codificador de vídeo, de forma geral, é composto por três partes principais:
módulo temporal, módulo espacial e codificador de entropia. Cada um desses módulos é
responsável por remover um tipo de redundância presente no vídeo (AGOSTINI, 2007):
a) Redundância Espacial: devida à correlação existente entre os pixeis ao longo de
um quadro (por isso, chamada intraquadro). A remoção dessa redundância é
realizada no domínio espacial e no domínio das frequências, pela predição
intraquadro e quantização, respectivamente. A quantização é uma operação
irreversível, pois gera perdas na codificação. No entanto, as perdas tendem a ser
pouco significativas na qualidade visual da imagem.
b) Redundância Temporal: se deve à correlação existente entre os diversos quadros
(por isso, chamada interquadro) temporalmente adjacentes. Essas redundância
pode ser visualizada como uma dimensão adicional da redundância espacial
(GONZALEZ, 2000). Esta correlação temporal é tratada pelo módulos de
estimativa e compensação de movimento.
c) Redundância Entrópica: relaciona-se com a probabilidade de ocorrência de
determinados símbolos, sendo que quanto maior a probabilidade de ocorrência
de um determinado símbolo, menos informação estará sendo codificada através
dele. A codificação de entropia utiliza algoritmos de compressão sem perdas
objetivando a codificação da maior quantidade de informação possível por
símbolo. A entropia é a medida da quantidade média de informação codificada
por símbolo (SHI; SUN, 2007).
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
37
3.3 Introdução ao H.264
H.264 é um padrão internacional de codificação de vídeo para a indústria. É composto
por um documento publicado pela ITU-T e ISO/IEC (como sendo a parte 10 do MPEG-4) que
possui instruções que definem o formato do vídeo codificado. Além disso, é definido, em
detalhes, o funcionamento de um decodificador capaz de decodificar o formato especificado
(ITU-T, 2003).
Assim como em outros padrões de codificação, não são especificados os detalhes do
codificador. A única restrição imposta na implementação do codificador, é que ele precisa
gerar um bitstream (fluxo de vídeo codificado) conforme a especificação, de forma que possa
ser decodificado corretamente por qualquer implementação do decodificador
(RICHARDSON, 2003). O H.264 define um conjunto de técnicas e ferramentas de
compressão, o codificador pode optar por qual desses itens irá fazer uso.
O padrão H.264 foi originalmente publicado em 2003 e sofreu diversas revisões e
atualizações desde então. Os conceitos básicos deste codec são os mesmos presentes no
MPEG-2 e MPEG-4 Visual, no entanto, os avanços sugeridos proporcionam um aumento
potencial na eficiência, qualidade e flexibilidade da compressão (RICHARDSON, 2010).
3.4 Descrição do codec H.264
O codificador possui dois caminhos por onde os dados fluem: o caminho direto,
através do qual é gerado a sequência de bytes que representa o vídeo codificado e o caminho
de reconstrução do vídeo, através do qual o codificador monta os quadros decodificados a
serem usados como referência.
Inicialmente, cada macrobloco5
do quadro original a ser codificado é subtraído de um
macrobloco de referência obtido pela predição intraquadro ou pela compensação/estimativa
de movimento. Os macroblocos de referência utilizados são oriundos de quadros
reconstruídos pelo caminho de reconstrução, que executa as operações identicamente a um
decodificador (RICHARDSON, 2003).
Os macroblocos de diferenças (geralmente chamados de macroblocos de resíduos) são
processados pelos módulos de transformadas e quantização. Os coeficientes quantizados e as
informações de controle, que indicam as decisões tomadas pelo codificador, são repassadas ao
codificador de entropia que irá reduzir o nível de redundância entrópica do fluxo de bits de
saída (bitstream). Por fim, o vídeo codificado será colocado dentro de “pacotes”
5
Macrobloco é um bloco de 16x16 pixeis.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
38
padronizados, referenciados como NAL (Network Abstraction Layer) (RICHARDSON,
2003).
As técnicas de compressão baseadas em predição de blocos da imagem fazem uso de
blocos da vizinhança (temporal ou espacial) que foram codificados anteriormente ao bloco
atual. Tanto o codificador quanto o decodificador executam o procedimento de compensação,
de forma que o codificador utilize como quadro de referência o mesmo resultado que será
obtido pelo decodificador.
Portanto, o resultado quantizado será processado pelo bloco de quantização inversa e
transformadas inversas. O resultado desta etapa será somado ao resultado da predição
intraquadro ou interquadro e filtrado (para diminuir os efeitos do particionamento da imagem
em blocos) e então formará a próxima imagem de referência, ou seja, uma versão
decodificada do bloco original (RICHARDSON, 2003).
A Figura 8 apresenta os blocos constituintes do codificador H.264.
Figura 8 Estrutura do codificador H.264 (REDIESS, 2006).
3.4.1 Predição intraquadro
A predição intraquadro tem por objetivo diminuir a redundância espacial dentro um
quadro. Sua característica principal é permitir a compressão de dados de cada quadro de
forma auto contida, ou seja, cada quadro da sequência de vídeo pode ser processado de forma
independente de todos os demais. Este procedimento é aplicado a todos elementos dos
macroblocos no domínio espacial (AGOSTINI, 2007).
O padrão H.264 define a aplicação da predição intraquadro nos componentes de
luminância e crominância dos macroblocos I (Intra), resultando em macroblocos preditos com
base em amostras reconstruídas, ou seja, que já percorreram todo o caminho de reconstrução
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
39
do codificador. O resultado desta predição é subtraído do macrobloco original a fim de gerar
um macrobloco de resíduos a serem codificados.
Segundo a norma H.264, existem dois tipos de blocos I: de tamanho 4x4 e 16x16. No
primeiro caso o conjunto de 16x16 amostras é processado separadamente em blocos de 4x4.
Já no segundo caso, o macrobloco é tratado sem divisões. Para cara tipo de macrobloco I,
existem vários modos de predição que visam atacar determinados padrões espaciais no quadro
de vídeo. Por exemplo, as Figuras 9 e 10, apresentam os quatro modos de predição para
macroblocos I 16x16 e os nove modos de predição para macroblocos I 4x4, respectivamente
(RICHARDSON, 2003).
Figura 9 Modos de predição para blocos 16x16 de luminância. (AGOSTINI, 2007)
As crominâncias são processadas em blocos 8x8 e existem quatro modos de predição
possíveis. No entanto, as duas crominâncias sempre utilizam o mesmo modo
(RICHARDSON, 2003).
A decisão de qual modo de predição será empregado em cada macrobloco fica a cargo
do codificador. Existem duas abordagens para a tomada desta decisão: algoritmos de busca
completa (que calculam todos os modos possíveis a fim de encontrar qual fornece a melhor
eficiência na compressão) e algoritmos rápidos (que baseiam-se em alguma heurística, usando
informação do vídeo a ser codificado, de forma a diminuir a complexidade da decisão)
(AGOSTINI, 2007).
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
40
Figura 10 Modos de predição para blocos 4x4 de luminância (AGOSTINI, 2007).
3.4.2 Transformadas diretas e inversas
A codificação por transformadas é uma técnica de compressão que explora a
correlação entre os pixeis de uma imagem, sendo empregada tanto em codificação de imagens
quanto codificação de vídeo. Este estágio do codificador converte blocos da imagem de
entrada ou de resíduos da predição em outro domínio. O domínio para o qual os dados de
entrada são convertidos deve conter a informação original separada em componentes
descorrelacionadas e com a maior parte da energia do sinal concentrada em um pequeno
número de componentes. Além disso, é necessário que a transformada seja reversível, de
forma que seja possível voltar à representação original. A transformada adotada na maior
parte dos codecs é a DCT bidimensional (SHI; SUN, 2008).
O padrão H.264 define a utilização de duas transformadas: DCT e Transformada de
Hadamard. O codificador H.264 transforma e quantiza os blocos de coeficientes residuais. A
transformada utilizada é uma versão aproximada da DCT, chamada core transform. Após esta
etapa, em certos casos, é empregada a Transformada de Hadamard aos coeficientes DC6
obtidos na etapa anterior (RICHARDSON, 2003). As seções seguintes apresentarão os
detalhes de cada uma dessas transformadas.
6
Coeficientes DC são aqueles que possuem frequência zero.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
41
3.4.2.1 Transformada discreta de cossenos
A DCT é uma transformada derivada da Transformada de Fourier cujo objetivo é
converter um bloco de dados de entrada para o domínio das frequências. A equação 1 define a
DCT (RICHARDSON, 2003).
Y =A· X · A
T
(1)
Onde
Y é a matriz de saída
X é a matriz de entrada
A é a matriz de coeficientes da transformada
AT
é a matriz A transposta
A matriz A é definida pela Equação 2.
Aij=C i·
cos2j1·i ·
2n
(2)
Onde
Ci=0=

1
n
 (3)
Ci≠0=

2
n
 (4)
Onde i e j representam a posição do elemento na matriz (linha e coluna,
respectivamente) e n representa o número de linhas ou colunas do bloco.
A partir das Equações 2, 3 e 4 obtém-se a seguinte matriz de coeficientes para aplicar
a transformada em blocos 4x4:
A=
[
1
2
·cos0
1
2
·cos0
1
2
·cos0
1
2
·cos0

1
2
·cos

8 
1
2
·cos
3·
8 
1
2
·cos
5·
8 
1
2
·cos
7·
8

1
2
·cos
2·
8 
1
2
·cos
6·
8 
1
2
·cos
10·
8 
1
2
·cos
14·
8

1
2
·cos
3·
8 
1
2
·cos
9·
8 
1
2
·cos
15·
8 
1
2
·cos
21·
8
] (5)
A Figura 11 exemplifica o funcionamento desta transformada. É possível notar que o
bloco resultante (b) possui as componentes mais significativas concentradas na parte superior
esquerda do bloco.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
42
Figura 11 Bloco de entrada (a) e resultado da DCT (b) (RICHARDSON, 2003).
Como pode-se observar, implementações dessa transformada requerem o uso de
aproximações de fatores irracionais. Se forem adotadas diferentes aproximações no
codificador e no decodificador, pode haver uma certa discrepância entre predições usadas
como referência, resultando distorção na saída do processo de decodificação.
Padronizações anteriores, como o MPEG-2 ou MPEG-4 adotaram diferentes medidas
para minimizar o impacto dessas aproximações. No entanto, o H.264 (e outros codecs
recentes) abordaram esse problema definindo um algoritmo adequado à implementação com
aritmética inteira com precisão limitada, de forma a eliminar a necessidade da utilização de
valores aproximados. Além disso, a implementação das transformadas em aritmética inteira
contribui para a diminuição do custo computacional das transformações (HUSEMANN et al.,
2010).
A matriz da transformada definida em 5 pode ser reescrita da seguinte forma:
A=
[
a a a a
b c −c −b
a −a −a a
c −b b −c
] (6)
Onde
a=
1
2
(7)
b=

1
2
·cos

8
 (8)
c=

1
2
·cos
3·
8
(9)
Considerando-se as definições 1, 6, 7, 8 e 9 obtém-se:
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
43
Y =A· X · A
T
=
[
a a a a
b c −c −b
a −a −a a
c −b b −c
]· X ·
[
a b a c
a c −a −b
a −c −a b
a −b a −c
] (10)
que pode ser fatorada em:
Y =A· X · A
T
=C · X ·C
T
⊙E (11)
Y =
[
1 1 1 1
2 1 −1 −2
1 −1 −1 1
1 −2 2 −1
]·
[
1 2 1 1
1 1 −1 −2
1 −1 −1 2
1 −2 1 −1
]⊙
[
a
2 ab
2
a
2 ab
2
ab
2
b
2
4
ab
2
b²
4
a
2 ab
2
a²
ab
2
ab
2
b²
4
ab
2
b²
4
] (12)
Onde ⊙ significa que cada elemento da matriz C · X · CT
é multiplicado pelo
elemento correspondente na matriz E. Essa multiplicação ponto-a-ponto não é efetivamente
calculada na implementação da DCT, no entanto, estes fatores de escala são compensados
durante a quantização.
Os fatores a e b da matriz E são aproximados para simplificar a implementação.
a=
1
2
(13)
b=

2
5
 (14)
A DCT inversa é necessária para transformar os dados para o seu domínio original,
tanto no decodificador quanto no laço de realimentação do codificador. A DCT inversa é
definida pela Equação 15.
X =A
T
·Y · A (15)
Onde
X é a matriz recuperada
Y é a matriz transformada
A é a matriz de coeficientes da transformada
AT
é a matriz A transposta
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
44
As mesmas considerações feitas na transformada direta são aplicadas à transformada
inversa, de forma a obter a operação inversa equivalente, resultando na Equação 16. A
multiplicação ponto-a-ponto, analogamente, será compensada na quantização inversa.
X =A
T
· X · A=
[
1 1 1
1
2
1
1
2
−1 −1
1 −
1
2
 −1 1
1 −1 1 −
1
2

]· X ·
[
1 1 1 1
1
1
2
−
1
2
 −1
1 −1 −1 1
1
2
−1 1 −
1
2
] (16)
3.4.2.2 Transformada de Hadamard
O padrão H.264 define a aplicação da transformada de Hadamard aos coeficientes DC
dos blocos após o cálculo da DCT, de forma aumentar a compressão em áreas homogêneas
(RICHARDSON, 2003). Por exemplo, um macrobloco de luminâncias (16 blocos de 4x4
amostras) resulta em um bloco 4x4 de componentes DC a serem processadas pela
transformada de Hadamard. No caso de um macrobloco de crominâncias, o bloco de
componentes DC é 2x2, devido à utilização de subamostragem nas crominâncias. A Figura 12
destaca os componentes DC dentro dos macroblocos de crominância (a) e luminância (b).
Figura 12 Macroblocos de crominância e luminância com componentes DC destacados
(MAJOLO, 2010).
A definição matricial da transformada de Hadamard, aplicada às amostras de
luminância, é apresentada na Equação 17.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
45
Y L=
1
2
·
[
1 1 1 1
1 1 −1 −1
1 −1 −1 1
1 −1 1 −1
]· X L ·
[
1 1 1 1
1 1 −1 −1
1 −1 −1 1
1 −1 1 −1
] (17)
Onde
XL é matriz 4x4 dos coeficientes DC resultantes da execução da DCT em um
bloco de 16x16 luminâncias;
YL é a matriz com os resultados obtidos pela transformada de Hadamard.
Quando aplicada às amostras de crominâncias, a transformada é definida pela Equação
18.
Y L=[1 1
1 −1]· XC ·[1 1
1 −1] (18)
Onde
XC é a matriz com os valores DC resultantes da DCT aplicada às crominâncias
YL é a matriz que contém o resultado da transformada.
A equação da transformada inversa de Hadamard (para blocos 4x4 de luminâncias) é
obtida através da manipulação da Equação 17, resultando em:
X L=
1
8
·
[
1 1 1 1
1 1 −1 −1
1 −1 −1 1
1 −1 1 −1
]·Y L ·
[
1 1 1 1
1 1 −1 −1
1 −1 −1 1
1 −1 1 −1
] (19)
A divisão por oito na Equação 19 não é realizada no cálculo da Hadamard inversa, no
entanto, é compensado durante a quantização inversa.
O mesmo procedimento aplicado à Equação 18 resulta na equação para transformada
inversa de Hadamard aplicada aos blocos 2x2 de crominâncias.
XC =[1 1
1 −1]·YC ·[1 1
1 −1] (20)
3.4.3 Quantização
O padrão H.264 conta com um módulo quantizador escalar. A quantização dos
coeficientes obtidos pelas transformadas resulta na redução da informação e,
consequentemente, na compressão dos dados.
A quantização consiste, basicamente, de uma divisão por valor inteiro, de maneira a
reduzir a faixa dos valores (RICHARDSON, 2003).
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
46
A equação básica que define a quantização é:
FQij=round 
Xij
Qstep
 (21)
Onde
FQ é o resultado da quantização;
X é o valor a ser quantizado;
Qstep é o passo de quantização;
round é uma função que aproxima o valor para o inteiro mais próximo.
O parâmetro Qstep determina a intensidade da quantização, ou seja, quanto maior o
Qstep maior a compressão atingida e, consequentemente, maior a perda de informação gerada
no arredondamento. A determinação do valor do Qstep é um passo importante na
configuração do codificador (MAJOLO, 2010).
A determinação do Qstep é realizada indiretamente através de uma tabela com 52
valores que podem ser assumidos pelo Qstep, que são indexados pelo Quantization
Parameter (QP). A relação entre o Qstep e QP é a seguinte: para cada incremento de seis
unidades do QP, o Qstep é multiplicado por dois.
Essa relação é apresentada na Tabela 3. A utilização desta tabela foi adotada a fim de
evitar a necessidade de operações custosas como, cálculos com ponto flutuante e divisões
(RICHARDSON, 2003).
Tabela 3 Passos de quantização.
QP 0 1 2 3 4 5 6 7 8 9 10 11 12 ...
Qstep 0,625 0,6875 0,8125 0,875 1 1,125 1,25 1,37
5
1,62
5
1,75 2 2,25 2,5
QP ... 18 ... 24 ... 30 ... 36 ... 42 ... 48 ... 51
Qstep 5 10 20 40 80 160 224
Fonte: RICHARDSON, 2003
Como foi mencionado na subseção sobre a transformada DCT, uma multiplicação
escalar oriunda daquela transformada não é implementada, precisando ser compensada
durante a quantização. Essa compensação é feita através da variável Post-Scaling Factor (PF),
definida pela Tabela 4, resultando na Equação 22. As variáveis a e b são definidas nas
Equações 13 e 14.
FQij=round X ij ·
PF
Qstep
 (22)
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
47
Tabela 4 Valores de PF para cada posição.
Posição (i, j) PF
(0,0), (2,0), (0,2) e (2,2) a²
(1,1), (1,3), (3,1) e (3,3) b²/4
Outras ab/2
Fonte: RICHARDSON, 2003.
Para fins de substituir divisões por deslocamento de bits, o termo PF / Qstep na
Equação 22 pode ser substituído por:
PF
Qstep
=
MF
2
qbits (23)
Onde
MF é o fator de multiplicação definido na Tabela 5;
qbits é definido por
qbits=15 floor 
QP
6
 (24)
sendo floor a função que realiza o arredondamento para baixo.
A equação final, em aritmética inteira, é expressa por:
∣FQij ∣=∣X ij ∣· MF f ≫qbits (25)
signFQij =signX ij  (26)
Onde
f é 2qbits
/3 para blocos da predição intra e 2qbits
/6 para blocos da predição inter;
>> é o descolocamento binário para direita;
sign é a função que acessa o sinal do número.
Tabela 5 Fator de multiplicação.
Posições Posições
QP (0,0), (2,0), (2,2) e (0,2) (1,1), (1,3), (3,1) e (3,3) Outras posições
0 13107 5243 8066
1 11916 4660 7490
2 10082 4194 6554
3 9362 3647 5825
4 8192 3355 5243
5 7282 2893 4559
Fonte: RICHARDSON, 2003.
Por fim, apresenta-se a definição da quantização inversa, que serve para recuperar o
valor anterior. Como a quantização é um procedimento que causa perdas, o valor recuperado é
uma aproximação do valor original, que depende do parâmetro QP. Este parâmetro terá o
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
48
mesmo valor na quantização direta e inversa. A equação da quantização inversa para os
componentes AC7
de luminâncias é definida em 27.
X 'ij=FQij ·Vij ·2
QP/6
(27)
Onde
X'ij é o valor recuperado;
FQij é o valor quantizado;
Vij é uma constante definida em 28;
QP é o parâmetro de quantização.
Vij=Qstep · PFij ·64 (28)
A quantização inversa para os componentes DC é expressa pela equação 29.
X 'ij=FQij ·V0,0 ·2
 floor QP/6
para QP >= 12
X 'ij=[ FQij ·V0,0 ·2
1− floor QP/6
]≫QP/6 para QP < 12
(29)
Onde
floor é operação que arredonda o número para baixo;
>> é deslocamento binário para direita.
3.4.4 Estimativa de movimento
A estimação de movimento trabalha no modelo temporal do vídeo com o objetivo de
encontrar e remover dados redundantes em quadros temporalmente adjacentes, algo
relativamente comuns em sequências de vídeo naturais. A partir do modelo temporal,
aproveitam-se as similaridades entres os quadros baseando-se em dados previamente
processados a fim de obter um quadro estimado (RICHARDSON, 2002).
A Figura 13 apresenta dois quadros temporalmente consecutivos no vídeo. Já a Figura
14a ilustra a similaridade entre os dois quadros através da codificação diferencial, ou seja, o
quadro é obtido através da simples subtração entre os dois quadros originais.
Nas figuras, o tom acinzentado predominante indica as regiões em que não há
diferença entre os dois quadros, o que pode ser explorado para reduzir a quantidade de dados
realmente necessários para construir a segunda imagem a partir da primeira.
A utilização das técnicas de estimação de movimento possibilitam reduzir os resíduos
obtidos pela codificação diferencial. A Figura 14b ilustra o resíduo obtido após a realização
da estimação de movimento.
7
Coeficientes AC são aqueles que possuem frequência diferente de zero.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
49
(a) (b)
Figura 13 Quadros consecutivos de vídeo (RICHARDSON, 2003).
(a) (b)
Figura 14 Na esquerda, o resíduo sem estimativa de movimento. Na direita, o resíduo com
estimativa de movimento (RICHARDSON, 2003).
A obtenção da estimativa de movimento se dá pela determinação de qual bloco dos
quadros de referência mais se assemelha ao macrobloco que está sendo processado, a fim de
que possa-se codificar apenas a diferença entre o bloco atual e o bloco selecionado e um vetor
de movimento que define a posição da região usada na predição. Este vetor é incluído no
bitstream de forma a permitir ao decodificador a realização do processo inverso
(compensação de movimento) (PORTO, 2008).
A estimação de movimento baseia-se em algoritmos de busca, que visam encontrar o
bloco que possui a maior similaridade com o bloco atual (melhor casamento), e em critérios
de similaridade que serão detalhados nas subseções seguintes.
A Figura 15 ilustra o procedimento de estimativa de movimento, que em conjunto com
a compensação de movimento constitui a predição interquadro. Segundo (PURI; CHEN;
LUTHRA, 2004) o codificador interquadros é o módulo que contém a maior complexidade
computacional em um codificador de vídeo.
O padrão H.264/AVC inovou na predição interquadro ao inserir a possibilidade de
blocos de tamanho variável, interpolação de valores intermediários (atingindo resolução de
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
50
meio ou quarto de pixel) e utilização de múltiplos quadros de referência (incluindo quadros
futuros) (RICHARDSON, 2003).
Figura 15 Predição interquadro (DINIZ, 2009).
3.4.4.1 Algoritmos de busca
Os algoritmos de busca especificam como a busca pelo bloco com maior similaridade
será realizada dentro de uma área de tamanho pré-definido chamada janela de busca. Em
geral, os algoritmos mais utilizados são os baseados em blocos de pixeis (em oposição aos
baseados em objetos). A escolha de um algoritmo de busca é extremamente importante, pois
tem impacto significativo, tanto na eficiência da compressão, quanto na complexidade
computacional do codificador (PORTO, 2012).
Os algoritmos de busca podem ser divididos em algoritmos ótimos e rápidos: os
algoritmos ótimos obtém o vetor de movimento correspondente ao bloco com maior
similaridade em relação ao bloco atual através da análise de todos os possíveis candidatos. Por
outro lado, os algoritmos rápidos obtém uma diminuição do tempo de busca através de
heurísticas que diminuem a quantidade de candidatos a serem analisados, ao custo de obterem
um vetor de movimento subótimo (PORTO, 2008).
O algoritmo Full Search (FS) é um algoritmo ótimo, pois compara a similaridade de
todos os possíveis blocos dentro da janela de busca. A iteração sobre todos os candidatos pode
ser de diversas formas, começando no canto superior esquerdo e finalizando no canto inferior
direito ou realizando uma busca em formato de espiral ao redor de uma posição central, por
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
51
exemplo. Os diferentes blocos candidatos são obtidos através do deslocamento da borda do
bloco em uma amostra, conforme ilustrado na Figura 16.
Figura 16 Algoritmo de busca completa (PORTO, 2012)
O algoritmo FS dificilmente é empregado em aplicações práticas que requerem
codificação em tempo real de altas resoluções, a menos que seja utilizada uma arquitetura
desenvolvida especialmente para este fim. Este algoritmo não possui dependência de dados,
portanto, é possível explorar um grande nível de paralelismo (SOARES, 2007).
Os algoritmos rápidos tentam obter bons vetores de movimentos mesmo sem fazer
uma busca exaustiva, ou seja, sem testar todos os possíveis blocos. Dentre as diversas formas
de realizar a busca propostas na literatura, a seguir serão abordados dois algoritmos de
interesse no contexto deste trabalho: Diamond Search (DS) e Logarithmic Search (LS).
O algoritmo DS é um algoritmo rápido que realiza a busca em um formato de
diamante. Este formato determina a posição dos blocos considerados candidatos dentro da
janela de busca. Usualmente, esse algoritmo emprega dois padrões de busca: Large Diamond
Search (LDS) e Small Diamond Search (SDS) (ZHU; MA, 2000).
Inicialmente a LDS compara as similaridades entre o bloco atual e nove blocos
candidatos ao redor da posição central da janela de busca. Se o bloco que resultar no menor
resíduo não estiver no centro do diamante, esta etapa será repetida com base em uma nova
posição central localizada no melhor bloco encontrado. Este procedimento se repete até que o
bloco de maior similaridade esteja na posição central. Num segundo momento, a SDS realiza
um refinamento ao redor da posição determinada na etapa anterior. Para tanto, é realizada a
comparação entre a similaridade da posição central e de quatro blocos vizinhos. A Figura 17
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
52
ilustra este procedimento. As posições “L” fazem parte do diamante grande e “S” do diamante
pequeno.
Figura 17 Large Diamond Search (LDS) e Small Diamond Search (SDS) (PORTO, 2008)
O algoritmo LS, inicialmente, compara o bloco atual com cinco blocos candidatos: a
posição (0, 0) e quatro blocos a S pixeis da origem na horizontal e na vertical, onde S é o
valor do passo inicial. Na etapa seguinte, a origem é posicionada no melhor bloco encontrado
na etapa anterior e o procedimento é repetido nessa nova posição. Quando o melhor
casamento ocorrer na posição central o valor do passo é dividido por dois, até que o passo
chegue ao valor um. Na sequência, as oito posições ao redor do bloco anteriormente
selecionado são testadas. O bloco com menor similaridade nesta etapa resulta no vetor de
movimento para a realização da predição.
A Figura 18 ilustra o funcionamento do algoritmo LS com o passo S valendo dois
inicialmente. No exemplo dado, para cada iteração da busca o bloco com maior similaridade é
destacado em negrito.
Figura 18 Algoritmo de busca logarítmica (RICHARDSON, 2002).
A quantidade de iterações executadas na LDS depende do vídeo em questão, o que
dificulta a análise do desempenho. Entretanto, o algoritmo DS diminui, em média, cerca de
150 vezes o número de blocos candidatos a terem a similaridade calculada e comparada, em
relação ao algoritmo de busca completa (PORTO, 2012). No padrão de busca LS ocorre a
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
53
mesma situação: o número de comparações necessárias depende da quantidade de iterações
efetuadas e varia em cada caso.
Uma técnica muitas vezes empregada conjuntamente a algoritmos de busca rápidos
como DS e LS é a determinação de uma posição inicial para a busca diferente de (0, 0) através
de vetores de movimento previamente obtidos (TOURAPIS, 2001). Por exemplo, pode-se
determinar a posição inicial da busca baseando-se nos vetores de movimento encontrados nos
blocos adjacentes do quadro atual. Essa ideia explora a localidade espacial, ou seja, o fato de
que blocos vizinhos tendem a ter movimentação semelhante. No entanto, dessa forma cria-se
uma dependência de dados entre os blocos de um mesmo quadro, o que dificulta a utilização
de paralelismo em nível de bloco. Uma outra alternativa é escolher a posição inicial de busca
a partir de dados proveniente de quadros previamente processados, ou seja, a exploração da
localidade temporal. Essa ideia baseia-se na premissa de que o mesmo bloco em quadros
temporalmente adjacentes possuam movimentação semelhante. Essa abordagem cria uma
dependência de dados entre os quadros, mas, possibilita o paralelismos em nível de blocos
dentro de um mesmo quadro.
3.4.4.2 Critérios de similaridade
Os critérios de similaridade são usados para determinar o grau de semelhança entre
dois blocos de pixeis. Diversos critérios foram propostos na literatura: Mean Square Error
(MSE), Mean Absolute Error (MAE), Sum of Absolute Differences (SAD) entre outros
(RICHARDSON, 2002).
A Equação 30 define o cálculo do SAD, que é usualmente empregado na estimativa de
movimento devido a sua simplicidade e em resultar em uma boa aproximação da energia do
bloco (PORTO, 2012).
SAD=∑
i =0
N −1
∑
j=0
N −1
∣Cij−Rij ∣ (30)
Onde
N é o tamanho do bloco
Cij é o pixel na posição (i,j) do bloco atual
Rij é o pixel na posição (i,j) do bloco de referência
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
54
3.4.5 Compensação de movimento
A compensação de movimento tem por objetivo encontrar, a partir do vetor de
movimento obtido pela estimação de movimento, os blocos mais semelhantes com o atual
dentre os blocos previamente codificados para obter o bloco predito. Para tanto, a
compensação de movimento necessita obter os parâmetros gerados pela estimação de
movimento (AZEVEDO, 2006).
O vídeo será, inicialmente, reconstruído com base no quadro predito. Em seguida,
serão corrigidas as diferenças entre o quadro original e o quadro estimado, utilizando o quadro
residual.
3.5 Trabalhos relacionados
Sprandlin et al. (2009) avaliaram a viabilidade de paralelizar a implementação de
referência do codificador MPEG-2, utilizando a tecnologia CUDA, e obtiveram significativos
ganhos de velocidade em partes específicas da implementação. No entanto, esses resultados
são severamente diluídos se analisado o aplicativo como um todo. Foi destacada a
importância de minimizar as transferências de dados entre a CPU e a placa de vídeo, pois a
alta latência e a pequena largura de banda do barramento PCIe foram apontadas como fatores
que limitaram os resultados.
Chan et al. (2009) demonstraram a viabilidade de implementar o algoritmo piramidal
de estimação de movimento do padrão H.264 utilizando CUDA. O resultado obtido foi uma
diminuição de 56 vezes no tempo gasto na execução do algoritmo, no entanto, foi utilizada
uma aproximação do vetor predito a fim de eliminar interdependências que diminuiriam o
nível de paralelismo alcançável.
Ren et al. (2010) propuseram duas implementações do módulo de predição-intra do
codificador H.264 em GPU. Na primeira implementação, foram eliminados dois modos de
predição a fim de alcançar um maior paralelismo em nível de blocos 4x4. A outra alternativa
explora o paralelismo em nível de macrobloco. No entanto, para eliminar as dependências
entre macroblocos vizinhos é necessária uma alteração no algoritmo (com consequências
insignificantes na qualidade em vídeos de alta definição). Os ganhos obtidos nas duas
implementações propostas ficaram em torno de cinco vezes em relação à implementação de
referência.
Huang, Shen e Wu (2009) estudaram a utilização de CPUs multi núcleo em conjunto
com GPUs, atuando como coprocessadores, para a implementação de um codificador de vídeo
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
55
H.264/SVC (extensão do H.264/AVC com técnicas de codificação escalável). Foi estudada a
divisão das tarefas entre as duas arquiteturas (CPUs e GPUs) e a transição de dados entre elas.
Os resultados obtidos apontaram que a execução do algoritmo de busca completa na
estimativa de movimento na GPU resultou em melhor desempenho se comparado à
implementação utilizando CPU multi núcleo.
Cheung et al. (2010) investigaram o uso de GPUs para codificação e decodificação de
vídeo. Este trabalho faz uma revisão da literatura acerca da estruturação e particionamento
dos módulos entre CPU e GPU. Por fim, é implementada a estimativa de movimento do
H.264 na GPU, através da qual é explorado o trade-off entre os ganhos de velocidade e a
qualidade obtida. Os experimentos levam a resultados de execução cerca de três vezes mais
rápida com a utilização da GPU e foi destacada a importância de expor o máximo paralelismo
de dados possível à GPU.
Monteiro et al. (2011) exploraram o uso da arquitetura CUDA no contexto da
estimativa de movimento, obtendo um ganho de velocidade de 600 vezes na implementação
do algoritmo de busca completa.
BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu)
56
4 DESCRIÇÃO DO SISTEMA DESENVOLVIDO
O aumento na complexidade computacional no padrão H.264 em relação aos padrões
anteriores é significante. Essa característica torna desafiadora a implementação de um sistema
capaz de executar a codificação em tempo real, especialmente para vídeos de alta resolução
(DINIZ, 2009). Inserido nesse contexto, o presente trabalho consiste na investigação da
utilização de GPUs, presentes nas placas de vídeo da NVIDIA, como coprocessadores no
contexto da codificação de vídeo. Para tanto, utilizou-se a tecnologia NVIDIA CUDA,
apresentada no segundo capítulo deste trabalho.
Um ponto importante foi a identificação dos algoritmos de codificação de vídeo que
são apropriados à implementação em arquiteturas paralelas. Por isso, faz-se necessária a
revisão de literatura apresentada previamente e o estudo da implementação de referência do
codificador H.264.
A complexidade computacional dos diversos módulos do codificador H.264 foi
analisada em diversos trabalhos encontrados na literatura. Em geral, as análises consideram o
tempo de processamento necessário por cada módulo, o que equivale aproximadamente ao
número de operações executadas (HOROWITZ, 2003). A Tabela 6 apresenta o percentual da
complexidade computacional dos principais módulos do H.264, segundo a avaliação de Zhang
et al. (2005).
Tabela 6 Complexidade dos módulos do codificador H.264.
Módulo Complexidade %
ME / MC 81,78
T / Q / T-1
/ Q-1
5,49
Predição intraquadro 5,29
Filtro 0,82
Outros 6,62
Fonte: ZHANG et al., 2003.
Pode-se notar claramente que a parcela mais significativa localiza-se na estimativa e
compensação de movimento. Essas técnicas situam-se na predição interquadro, ou seja,
exploram as redundâncias temporais do vídeo. Por outro lado, na exploração das redundâncias
espaciais dentro de um quadro do vídeo, destacam-se as transformadas e quantização diretas e
inversas (que juntas compõe o que pode ser chamado de módulo computacional) e a própria
predição intraquadro. O desenvolvimento deste trabalho foi dividido em duas etapas: o estudo
dos algoritmos relacionados à codificação intraquadro e codificação interquadro.
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU
Codificador H.264 GPU

Mais conteúdo relacionado

Semelhante a Codificador H.264 GPU

Troca de contexto segura em sistemas operacionais embarcados utilizando técni...
Troca de contexto segura em sistemas operacionais embarcados utilizando técni...Troca de contexto segura em sistemas operacionais embarcados utilizando técni...
Troca de contexto segura em sistemas operacionais embarcados utilizando técni...Rodrigo Almeida
 
Gerenciador do atmega16
Gerenciador do atmega16Gerenciador do atmega16
Gerenciador do atmega16Gabriel Lima
 
Conexão remota e segurança de rede
Conexão remota e segurança de redeConexão remota e segurança de rede
Conexão remota e segurança de redeSoftD Abreu
 
SISTEMA DE INTERPRETAÇÃO DE ARQUIVOS FAT32 E DECODIFICAÇÃO DE MPEG UTILIZANDO...
SISTEMA DE INTERPRETAÇÃO DE ARQUIVOS FAT32 E DECODIFICAÇÃO DE MPEG UTILIZANDO...SISTEMA DE INTERPRETAÇÃO DE ARQUIVOS FAT32 E DECODIFICAÇÃO DE MPEG UTILIZANDO...
SISTEMA DE INTERPRETAÇÃO DE ARQUIVOS FAT32 E DECODIFICAÇÃO DE MPEG UTILIZANDO...jamesfrk
 
Proposta para Aceleração de Desempenho de Algoritmos de Visão Computacional e...
Proposta para Aceleração de Desempenho de Algoritmos de Visão Computacional e...Proposta para Aceleração de Desempenho de Algoritmos de Visão Computacional e...
Proposta para Aceleração de Desempenho de Algoritmos de Visão Computacional e...André Curvello
 
Tcc leonildo wagner reestruturação de website utilizando padrões w3 c 26-04...
Tcc leonildo wagner   reestruturação de website utilizando padrões w3 c 26-04...Tcc leonildo wagner   reestruturação de website utilizando padrões w3 c 26-04...
Tcc leonildo wagner reestruturação de website utilizando padrões w3 c 26-04...Léo Dias
 
[PRJ32][Christopher] aula 1 – introdução
[PRJ32][Christopher] aula 1 – introdução[PRJ32][Christopher] aula 1 – introdução
[PRJ32][Christopher] aula 1 – introduçãoChristopher Cerqueira
 
DESENVOLVIMENTO_DE_FIRMWARE_E_SOFTWARE_D.pdf
DESENVOLVIMENTO_DE_FIRMWARE_E_SOFTWARE_D.pdfDESENVOLVIMENTO_DE_FIRMWARE_E_SOFTWARE_D.pdf
DESENVOLVIMENTO_DE_FIRMWARE_E_SOFTWARE_D.pdfJulioCesar547337
 
TCC - AUTOMAÇÃO RESIDENCIAL - BRUNO GASTALDI
TCC - AUTOMAÇÃO RESIDENCIAL - BRUNO GASTALDITCC - AUTOMAÇÃO RESIDENCIAL - BRUNO GASTALDI
TCC - AUTOMAÇÃO RESIDENCIAL - BRUNO GASTALDIBruno Gastaldi
 
TV Digital interativa - Projeto TeouVi
TV Digital interativa - Projeto TeouViTV Digital interativa - Projeto TeouVi
TV Digital interativa - Projeto TeouViLucas Augusto Carvalho
 
TCC - SISTEMA PARA MONITORAMENTO DO GÁS AMÔNIA EM AVIÁRIOS
TCC - SISTEMA PARA MONITORAMENTO DO GÁS AMÔNIA EM AVIÁRIOSTCC - SISTEMA PARA MONITORAMENTO DO GÁS AMÔNIA EM AVIÁRIOS
TCC - SISTEMA PARA MONITORAMENTO DO GÁS AMÔNIA EM AVIÁRIOSJean Luiz Zanatta
 
WebTV: Um novo método para assistir TV.
WebTV: Um novo método para assistir TV.WebTV: Um novo método para assistir TV.
WebTV: Um novo método para assistir TV.Rafael Macedo
 
Maquina de bebidas AC_80_C51
Maquina de bebidas AC_80_C51Maquina de bebidas AC_80_C51
Maquina de bebidas AC_80_C51Vitor Faria
 
WebTV: Um novo método para assistir TV
WebTV: Um novo método para assistir TVWebTV: Um novo método para assistir TV
WebTV: Um novo método para assistir TVRafael Macedo
 

Semelhante a Codificador H.264 GPU (20)

Troca de contexto segura em sistemas operacionais embarcados utilizando técni...
Troca de contexto segura em sistemas operacionais embarcados utilizando técni...Troca de contexto segura em sistemas operacionais embarcados utilizando técni...
Troca de contexto segura em sistemas operacionais embarcados utilizando técni...
 
Gerenciador do atmega16
Gerenciador do atmega16Gerenciador do atmega16
Gerenciador do atmega16
 
Projeto BECI
Projeto BECIProjeto BECI
Projeto BECI
 
Conexão remota e segurança de rede
Conexão remota e segurança de redeConexão remota e segurança de rede
Conexão remota e segurança de rede
 
Tese de mestrado
Tese de mestradoTese de mestrado
Tese de mestrado
 
SISTEMA DE INTERPRETAÇÃO DE ARQUIVOS FAT32 E DECODIFICAÇÃO DE MPEG UTILIZANDO...
SISTEMA DE INTERPRETAÇÃO DE ARQUIVOS FAT32 E DECODIFICAÇÃO DE MPEG UTILIZANDO...SISTEMA DE INTERPRETAÇÃO DE ARQUIVOS FAT32 E DECODIFICAÇÃO DE MPEG UTILIZANDO...
SISTEMA DE INTERPRETAÇÃO DE ARQUIVOS FAT32 E DECODIFICAÇÃO DE MPEG UTILIZANDO...
 
Proposta para Aceleração de Desempenho de Algoritmos de Visão Computacional e...
Proposta para Aceleração de Desempenho de Algoritmos de Visão Computacional e...Proposta para Aceleração de Desempenho de Algoritmos de Visão Computacional e...
Proposta para Aceleração de Desempenho de Algoritmos de Visão Computacional e...
 
Tcc leonildo wagner reestruturação de website utilizando padrões w3 c 26-04...
Tcc leonildo wagner   reestruturação de website utilizando padrões w3 c 26-04...Tcc leonildo wagner   reestruturação de website utilizando padrões w3 c 26-04...
Tcc leonildo wagner reestruturação de website utilizando padrões w3 c 26-04...
 
SIC_201_VRSJ
SIC_201_VRSJSIC_201_VRSJ
SIC_201_VRSJ
 
[PRJ32][Christopher] aula 1 – introdução
[PRJ32][Christopher] aula 1 – introdução[PRJ32][Christopher] aula 1 – introdução
[PRJ32][Christopher] aula 1 – introdução
 
DESENVOLVIMENTO_DE_FIRMWARE_E_SOFTWARE_D.pdf
DESENVOLVIMENTO_DE_FIRMWARE_E_SOFTWARE_D.pdfDESENVOLVIMENTO_DE_FIRMWARE_E_SOFTWARE_D.pdf
DESENVOLVIMENTO_DE_FIRMWARE_E_SOFTWARE_D.pdf
 
Embarcados
EmbarcadosEmbarcados
Embarcados
 
TCC - AUTOMAÇÃO RESIDENCIAL - BRUNO GASTALDI
TCC - AUTOMAÇÃO RESIDENCIAL - BRUNO GASTALDITCC - AUTOMAÇÃO RESIDENCIAL - BRUNO GASTALDI
TCC - AUTOMAÇÃO RESIDENCIAL - BRUNO GASTALDI
 
TV Digital interativa - Projeto TeouVi
TV Digital interativa - Projeto TeouViTV Digital interativa - Projeto TeouVi
TV Digital interativa - Projeto TeouVi
 
Treino redes2003
Treino redes2003Treino redes2003
Treino redes2003
 
070498 t2
070498 t2070498 t2
070498 t2
 
TCC - SISTEMA PARA MONITORAMENTO DO GÁS AMÔNIA EM AVIÁRIOS
TCC - SISTEMA PARA MONITORAMENTO DO GÁS AMÔNIA EM AVIÁRIOSTCC - SISTEMA PARA MONITORAMENTO DO GÁS AMÔNIA EM AVIÁRIOS
TCC - SISTEMA PARA MONITORAMENTO DO GÁS AMÔNIA EM AVIÁRIOS
 
WebTV: Um novo método para assistir TV.
WebTV: Um novo método para assistir TV.WebTV: Um novo método para assistir TV.
WebTV: Um novo método para assistir TV.
 
Maquina de bebidas AC_80_C51
Maquina de bebidas AC_80_C51Maquina de bebidas AC_80_C51
Maquina de bebidas AC_80_C51
 
WebTV: Um novo método para assistir TV
WebTV: Um novo método para assistir TVWebTV: Um novo método para assistir TV
WebTV: Um novo método para assistir TV
 

Último

PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...azulassessoria9
 
Slides Lição 5, Betel, Ordenança para uma vida de vigilância e oração, 2Tr24....
Slides Lição 5, Betel, Ordenança para uma vida de vigilância e oração, 2Tr24....Slides Lição 5, Betel, Ordenança para uma vida de vigilância e oração, 2Tr24....
Slides Lição 5, Betel, Ordenança para uma vida de vigilância e oração, 2Tr24....LuizHenriquedeAlmeid6
 
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...azulassessoria9
 
Revolução russa e mexicana. Slides explicativos e atividades
Revolução russa e mexicana. Slides explicativos e atividadesRevolução russa e mexicana. Slides explicativos e atividades
Revolução russa e mexicana. Slides explicativos e atividadesFabianeMartins35
 
PROJETO DE EXTENSÃO I - SERVIÇOS JURÍDICOS, CARTORÁRIOS E NOTARIAIS.pdf
PROJETO DE EXTENSÃO I - SERVIÇOS JURÍDICOS, CARTORÁRIOS E NOTARIAIS.pdfPROJETO DE EXTENSÃO I - SERVIÇOS JURÍDICOS, CARTORÁRIOS E NOTARIAIS.pdf
PROJETO DE EXTENSÃO I - SERVIÇOS JURÍDICOS, CARTORÁRIOS E NOTARIAIS.pdfHELENO FAVACHO
 
PROJETO DE EXTENSÃO - EDUCAÇÃO FÍSICA BACHARELADO.pdf
PROJETO DE EXTENSÃO - EDUCAÇÃO FÍSICA BACHARELADO.pdfPROJETO DE EXTENSÃO - EDUCAÇÃO FÍSICA BACHARELADO.pdf
PROJETO DE EXTENSÃO - EDUCAÇÃO FÍSICA BACHARELADO.pdfHELENO FAVACHO
 
planejamento_estrategico_-_gestao_2021-2024_16015654.pdf
planejamento_estrategico_-_gestao_2021-2024_16015654.pdfplanejamento_estrategico_-_gestao_2021-2024_16015654.pdf
planejamento_estrategico_-_gestao_2021-2024_16015654.pdfmaurocesarpaesalmeid
 
Considere a seguinte situação fictícia: Durante uma reunião de equipe em uma...
Considere a seguinte situação fictícia:  Durante uma reunião de equipe em uma...Considere a seguinte situação fictícia:  Durante uma reunião de equipe em uma...
Considere a seguinte situação fictícia: Durante uma reunião de equipe em uma...azulassessoria9
 
PROJETO DE EXTENSÃO I - TERAPIAS INTEGRATIVAS E COMPLEMENTARES.pdf
PROJETO DE EXTENSÃO I - TERAPIAS INTEGRATIVAS E COMPLEMENTARES.pdfPROJETO DE EXTENSÃO I - TERAPIAS INTEGRATIVAS E COMPLEMENTARES.pdf
PROJETO DE EXTENSÃO I - TERAPIAS INTEGRATIVAS E COMPLEMENTARES.pdfHELENO FAVACHO
 
Urso Castanho, Urso Castanho, o que vês aqui?
Urso Castanho, Urso Castanho, o que vês aqui?Urso Castanho, Urso Castanho, o que vês aqui?
Urso Castanho, Urso Castanho, o que vês aqui?AnabelaGuerreiro7
 
Discurso Direto, Indireto e Indireto Livre.pptx
Discurso Direto, Indireto e Indireto Livre.pptxDiscurso Direto, Indireto e Indireto Livre.pptx
Discurso Direto, Indireto e Indireto Livre.pptxferreirapriscilla84
 
Currículo - Ícaro Kleisson - Tutor acadêmico.pdf
Currículo - Ícaro Kleisson - Tutor acadêmico.pdfCurrículo - Ícaro Kleisson - Tutor acadêmico.pdf
Currículo - Ícaro Kleisson - Tutor acadêmico.pdfTutor de matemática Ícaro
 
About Vila Galé- Cadeia Empresarial de Hotéis
About Vila Galé- Cadeia Empresarial de HotéisAbout Vila Galé- Cadeia Empresarial de Hotéis
About Vila Galé- Cadeia Empresarial de Hotéisines09cachapa
 
Slides Lição 05, Central Gospel, A Grande Tribulação, 1Tr24.pptx
Slides Lição 05, Central Gospel, A Grande Tribulação, 1Tr24.pptxSlides Lição 05, Central Gospel, A Grande Tribulação, 1Tr24.pptx
Slides Lição 05, Central Gospel, A Grande Tribulação, 1Tr24.pptxLuizHenriquedeAlmeid6
 
apostila projeto de vida 2 ano ensino médio
apostila projeto de vida 2 ano ensino médioapostila projeto de vida 2 ano ensino médio
apostila projeto de vida 2 ano ensino médiorosenilrucks
 
Análise poema país de abril (Mauel alegre)
Análise poema país de abril (Mauel alegre)Análise poema país de abril (Mauel alegre)
Análise poema país de abril (Mauel alegre)ElliotFerreira
 
Bloco de português com artigo de opinião 8º A, B 3.docx
Bloco de português com artigo de opinião 8º A, B 3.docxBloco de português com artigo de opinião 8º A, B 3.docx
Bloco de português com artigo de opinião 8º A, B 3.docxkellyneamaral
 
Nós Propomos! " Pinhais limpos, mundo saudável"
Nós Propomos! " Pinhais limpos, mundo saudável"Nós Propomos! " Pinhais limpos, mundo saudável"
Nós Propomos! " Pinhais limpos, mundo saudável"Ilda Bicacro
 
Rota das Ribeiras Camp, Projeto Nós Propomos!
Rota das Ribeiras Camp, Projeto Nós Propomos!Rota das Ribeiras Camp, Projeto Nós Propomos!
Rota das Ribeiras Camp, Projeto Nós Propomos!Ilda Bicacro
 

Último (20)

PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
 
Slides Lição 5, Betel, Ordenança para uma vida de vigilância e oração, 2Tr24....
Slides Lição 5, Betel, Ordenança para uma vida de vigilância e oração, 2Tr24....Slides Lição 5, Betel, Ordenança para uma vida de vigilância e oração, 2Tr24....
Slides Lição 5, Betel, Ordenança para uma vida de vigilância e oração, 2Tr24....
 
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
 
Revolução russa e mexicana. Slides explicativos e atividades
Revolução russa e mexicana. Slides explicativos e atividadesRevolução russa e mexicana. Slides explicativos e atividades
Revolução russa e mexicana. Slides explicativos e atividades
 
PROJETO DE EXTENSÃO I - SERVIÇOS JURÍDICOS, CARTORÁRIOS E NOTARIAIS.pdf
PROJETO DE EXTENSÃO I - SERVIÇOS JURÍDICOS, CARTORÁRIOS E NOTARIAIS.pdfPROJETO DE EXTENSÃO I - SERVIÇOS JURÍDICOS, CARTORÁRIOS E NOTARIAIS.pdf
PROJETO DE EXTENSÃO I - SERVIÇOS JURÍDICOS, CARTORÁRIOS E NOTARIAIS.pdf
 
PROJETO DE EXTENSÃO - EDUCAÇÃO FÍSICA BACHARELADO.pdf
PROJETO DE EXTENSÃO - EDUCAÇÃO FÍSICA BACHARELADO.pdfPROJETO DE EXTENSÃO - EDUCAÇÃO FÍSICA BACHARELADO.pdf
PROJETO DE EXTENSÃO - EDUCAÇÃO FÍSICA BACHARELADO.pdf
 
planejamento_estrategico_-_gestao_2021-2024_16015654.pdf
planejamento_estrategico_-_gestao_2021-2024_16015654.pdfplanejamento_estrategico_-_gestao_2021-2024_16015654.pdf
planejamento_estrategico_-_gestao_2021-2024_16015654.pdf
 
Considere a seguinte situação fictícia: Durante uma reunião de equipe em uma...
Considere a seguinte situação fictícia:  Durante uma reunião de equipe em uma...Considere a seguinte situação fictícia:  Durante uma reunião de equipe em uma...
Considere a seguinte situação fictícia: Durante uma reunião de equipe em uma...
 
PROJETO DE EXTENSÃO I - TERAPIAS INTEGRATIVAS E COMPLEMENTARES.pdf
PROJETO DE EXTENSÃO I - TERAPIAS INTEGRATIVAS E COMPLEMENTARES.pdfPROJETO DE EXTENSÃO I - TERAPIAS INTEGRATIVAS E COMPLEMENTARES.pdf
PROJETO DE EXTENSÃO I - TERAPIAS INTEGRATIVAS E COMPLEMENTARES.pdf
 
Urso Castanho, Urso Castanho, o que vês aqui?
Urso Castanho, Urso Castanho, o que vês aqui?Urso Castanho, Urso Castanho, o que vês aqui?
Urso Castanho, Urso Castanho, o que vês aqui?
 
Discurso Direto, Indireto e Indireto Livre.pptx
Discurso Direto, Indireto e Indireto Livre.pptxDiscurso Direto, Indireto e Indireto Livre.pptx
Discurso Direto, Indireto e Indireto Livre.pptx
 
Aula sobre o Imperialismo Europeu no século XIX
Aula sobre o Imperialismo Europeu no século XIXAula sobre o Imperialismo Europeu no século XIX
Aula sobre o Imperialismo Europeu no século XIX
 
Currículo - Ícaro Kleisson - Tutor acadêmico.pdf
Currículo - Ícaro Kleisson - Tutor acadêmico.pdfCurrículo - Ícaro Kleisson - Tutor acadêmico.pdf
Currículo - Ícaro Kleisson - Tutor acadêmico.pdf
 
About Vila Galé- Cadeia Empresarial de Hotéis
About Vila Galé- Cadeia Empresarial de HotéisAbout Vila Galé- Cadeia Empresarial de Hotéis
About Vila Galé- Cadeia Empresarial de Hotéis
 
Slides Lição 05, Central Gospel, A Grande Tribulação, 1Tr24.pptx
Slides Lição 05, Central Gospel, A Grande Tribulação, 1Tr24.pptxSlides Lição 05, Central Gospel, A Grande Tribulação, 1Tr24.pptx
Slides Lição 05, Central Gospel, A Grande Tribulação, 1Tr24.pptx
 
apostila projeto de vida 2 ano ensino médio
apostila projeto de vida 2 ano ensino médioapostila projeto de vida 2 ano ensino médio
apostila projeto de vida 2 ano ensino médio
 
Análise poema país de abril (Mauel alegre)
Análise poema país de abril (Mauel alegre)Análise poema país de abril (Mauel alegre)
Análise poema país de abril (Mauel alegre)
 
Bloco de português com artigo de opinião 8º A, B 3.docx
Bloco de português com artigo de opinião 8º A, B 3.docxBloco de português com artigo de opinião 8º A, B 3.docx
Bloco de português com artigo de opinião 8º A, B 3.docx
 
Nós Propomos! " Pinhais limpos, mundo saudável"
Nós Propomos! " Pinhais limpos, mundo saudável"Nós Propomos! " Pinhais limpos, mundo saudável"
Nós Propomos! " Pinhais limpos, mundo saudável"
 
Rota das Ribeiras Camp, Projeto Nós Propomos!
Rota das Ribeiras Camp, Projeto Nós Propomos!Rota das Ribeiras Camp, Projeto Nós Propomos!
Rota das Ribeiras Camp, Projeto Nós Propomos!
 

Codificador H.264 GPU

  • 1. CENTRO UNIVERSITÁRIO UNIVATES CENTRO DE CIÊNCIAS EXATAS E TECNOLÓGICAS CURSO DE ENGENHARIA DE CONTROLE E AUTOMAÇÃO AUGUSTO LIMBERGER LENZ COMPUTAÇÃO PARALELA COM ARQUITETURA DE PROCESSAMENTO GRÁFICO CUDA APLICADA A UM CODIFICADOR DE VÍDEO H.264 Lajeado 2012
  • 2. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) AUGUSTO LIMBERGER LENZ COMPUTAÇÃO PARALELA COM ARQUITETURA DE PROCESSAMENTO GRÁFICO CUDA APLICADA A UM CODIFICADOR DE VÍDEO H.264 Trabalho de Conclusão de Curso apresentado ao Centro de Ciências Exatas e Tecnológicas do Centro Universitário UNIVATES, como parte dos requisitos para a obtenção do título de bacharel em Engenharia de Controle e Automação. Área de concentração: Computação paralela ORIENTADOR: Ronaldo Hüsemann Lajeado 2012
  • 3. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) AUGUSTO LIMBERGER LENZ COMPUTAÇÃO PARALELA COM ARQUITETURA DE PROCESSAMENTO GRÁFICO CUDA APLICADA A UM CODIFICADOR DE VÍDEO H.264 Este trabalho foi julgado adequado para a obtenção do título de bacharel em Engenharia de Controle e Automação do CETEC e aprovado em sua forma final pelo Orientador e pela Banca Examinadora. Orientador: ____________________________________ Prof. Ronaldo Hüsemann, UNIVATES Doutor pelo PPGEE/UFRGS – Porto Alegre, Brasil Banca Examinadora: Prof. Marcelo de Gomensoro Malheiros, UNIVATES Mestre pela FEEC/UNICAMP – Campinas, Brasil Prof. Maglan Cristiano Diemer, UNIVATES Mestre pelo PPGCA/UNISINOS – São Leopoldo, Brasil Coordenador do curso de Engenharia de Controle e Automação _______________________________ Prof. Rodrigo Wolff Porto Lajeado, Junho de 2012.
  • 4. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) Dedico este trabalho ao meu pai, Edu, e a minha mãe, Ivone, por acreditarem na importância da educação.
  • 5. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) AGRADECIMENTOS À minha família, pelo apoio, incentivo e compreensão nos momentos difíceis, no transcorrer da realização desse trabalho e demais atividades da graduação. Ao professor Ronaldo Hüsemann, pela sua orientação, pelas oportunidades de trabalhar em projetos de pesquisa e pela amizade cultivada ao longo desse período. Aos colegas do Laboratório de Engenharia Aplicada: Anderson Giacomolli, Diego Schwingel e Marco Gobbi pelas contribuições no desenvolvimento desse trabalho. Aos colegas de curso, pela amizade e companhia durante o decorrer desta jornada. À Luisa por todo o amor, carinho e compreensão.
  • 6. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) RESUMO Este trabalho investiga a utilização de processadores gráficos (GPUs) como coprocessadores em arquiteturas de computadores no contexto da codificação de vídeo. O objetivo específico é implementar módulos do codificador H.264 em tecnologia CUDA, presente nas placas de vídeo da empresa NVIDIA. Dessa forma, algoritmos paralelizáveis são executados na GPU de forma a acelerar a codificação e aliviar a carga da CPU principal. O primeiro estudo de caso foi a implementação do módulo computacional, situado no codificador intraquadro, que foi integrado ao software de referência para validação e testes. Os resultados obtidos apontam um ganho de cerca de 3,9 vezes no tempo de execução deste módulo para vídeos de alta definição. No segundo estudo de caso foi abordado o codificador interquadros através da estimação de movimento. Um algoritmo de busca adequado à arquitetura paralela em questão foi proposto e implementado, além da implementação do cálculo de SAD. Os resultados obtidos na estimação de movimento apontam para um aumento na velocidade de execução em torno de 5,7 vezes para vídeos de alta definição. Palavras-chaves: Codificação de Vídeo, Computação Paralela, GPGPU, CUDA.
  • 7. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) ABSTRACT This work investigates the use of graphical processing units (GPUs) as co-processors for computer architectures in the context of video encoding. The specific goal is to implement modules of the H.264 encoder in CUDA, present in NVIDIA video cards. Thus, parallelizable algorithms have been implemented on the GPU to accelerate the encoding and reduce the load of the main CPU. The first case study was the implementation of computational module, situated in the intra-frame encoder, that was integrated into the reference software for validation and testing. The results show a speedup of 3.9 times in the execution of computational module for high-definition video. In the second case study, the inter-frame encoder was approached through motion estimation. A search algorithm suitable for parallel architecture was proposed and implemented, in addition to the SAD calculation. The results show a speedup of 5.7 times in the execution for high-definition videos. Keywords: Video Coding, Parallel Computing, GPGPU, CUDA.
  • 8. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) SUMÁRIO 1 INTRODUÇÃO...................................................................................................................15 2 UNIDADE DE PROCESSAMENTO GRÁFICO............................................................19 2.1 Histórico das GPUs......................................................................................................19 2.1.1 Primeira geração...................................................................................................20 2.1.2 Segunda geração....................................................................................................20 2.1.3 Terceira Geração...................................................................................................21 2.1.4 Quarta geração......................................................................................................21 2.1.5 Quinta geração......................................................................................................22 2.2 Pipeline gráfico tradicional.........................................................................................22 2.3 Processamento de propósito geral em GPU...............................................................23 2.4 Visão Geral da CUDA..................................................................................................23 2.5 Arquitetura de hardware............................................................................................25 2.6 Modelo de programação..............................................................................................27 2.6.1 Função Kernel.......................................................................................................27 2.6.2 Hierarquia de threads...........................................................................................28 2.6.3 Hierarquia de memória........................................................................................29 2.7 Detalhamento dos espaços de memória......................................................................31 2.7.1 Registradores e memória local.............................................................................31 2.7.2 Memória compartilhada.......................................................................................31 2.7.3 Memória global.....................................................................................................32 2.7.4 Memória de textura e superfície..........................................................................33 2.7.5 Memória de constantes.........................................................................................34 3 CODIFICAÇÃO DE VÍDEO.............................................................................................35 3.1 Vídeo digital..................................................................................................................35 3.2 Compressão de vídeo...................................................................................................36 3.3 Introdução ao H.264....................................................................................................37 3.4 Descrição do codec H.264............................................................................................37 3.4.1 Predição intraquadro............................................................................................38 3.4.2 Transformadas diretas e inversas........................................................................40 3.4.2.1 Transformada discreta de cossenos..................................................................41 3.4.2.2 Transformada de Hadamard............................................................................44 3.4.3 Quantização...........................................................................................................45 3.4.4 Estimativa de movimento.....................................................................................48 3.4.4.1 Algoritmos de busca...........................................................................................50 3.4.4.2 Critérios de similaridade...................................................................................53 3.4.5 Compensação de movimento................................................................................54 3.5 Trabalhos relacionados............................................................................................54 4 DESCRIÇÃO DO SISTEMA DESENVOLVIDO...........................................................56 4.1 Codificação intraquadro..........................................................................................57 4.2 Algoritmos de computação intra................................................................................57 4.2.1 Implementação da DCT direta e inversa............................................................59 4.2.2 Implementação da Transformada de Hadamard..............................................59 4.2.3 Implementação da Quantização..........................................................................60
  • 9. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 4.3 Codificação interquadros........................................................................................61 4.3.1 Algorítimo de busca proposto..............................................................................61 4.3.2 Implementação da estimação de movimento......................................................62 5 RESULTADOS PRÁTICOS..............................................................................................66 5.1 Integração com o software de referência...................................................................66 5.2 Avaliação dos resultados no módulo computacional intra.......................................67 5.3 Avaliação do algoritmo de busca proposto................................................................69 5.4 Avaliação dos resultados da estimativa de movimento em GPU.............................71 5.5 GPU profiling...............................................................................................................75 6 CONCLUSÃO.....................................................................................................................77
  • 10. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) LISTA DE FIGURAS Figura 1 Shader tradicional x shader unificado, adaptado de (IKEDA, 2011).................24 Figura 2 Escalabilidade da arquitetura CUDA, adaptada de (NVIDIA, 2011a)..............25 Figura 3 Cenários comuns de branch divergence, adaptada de (HAN; ABDELRAHMAN , 2011).....................................................................................26 Figura 4 Organização das threads, adaptada de (NVIDIA, 2011a)...................................29 Figura 5 Fluxo típico de uma aplicação CUDA....................................................................30 Figura 6 Padrões de acesso coalescido (CONRAD, 2010)...................................................32 Figura 7 Acesso não coalescido (CONRAD, 2010)...............................................................33 Figura 8 Estrutura do codificador H.264 (REDIESS, 2006)...............................................38 Figura 9 Modos de predição para blocos 16x16 de luminância. (AGOSTINI, 2007).......39 Figura 10 Modos de predição para blocos 4x4 de luminância (AGOSTINI, 2007)..........40 Figura 11 Bloco de entrada (a) e resultado da DCT (b) (RICHARDSON, 2003).............42 Figura 12 Macroblocos de crominância e luminância com componentes DC destacados (MAJOLO, 2010)....................................................................................................44 Figura 13 Quadros consecutivos de vídeo (RICHARDSON, 2003)....................................49 Figura 14 Na esquerda, o resíduo sem estimativa de movimento. Na direita, o resíduo com estimativa de movimento (RICHARDSON, 2003)......................................49 Figura 15 Predição interquadro (DINIZ, 2009)...................................................................50 Figura 16 Algoritmo de busca completa (PORTO, 2012)...................................................51 Figura 17 Large Diamond Search (LDS) e Small Diamond Search (SDS) (PORTO, 2008) ..................................................................................................................................52 Figura 18 Algoritmo de busca logarítmica (RICHARDSON, 2002)..................................52 Figura 19 Processo de codificação intraquadro, adaptada de (DINIZ, 2009)...................57 Figura 20 Etapas do módulo computacional........................................................................58 Figura 21 Arquitetura proposta para módulo computacional usando GPUs NVIDIA (HUSEMANN et al., 2011b). ................................................................................58 Figura 22 Relacionamento das threads com os componentes DC......................................60 Figura 23 Padrão de busca do algoritmo proposto..............................................................62 Figura 24 Procedimento de redução usado no cálculo de SAD, adaptado de (NVIDIA, 2012).........................................................................................................................64 Figura 25 Distribuição do tempo entre as etapas.................................................................76
  • 11. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) LISTA DE CÓDIGOS Listagem 1 Declaração e chamada de um kernel.................................................................28 Listagem 2 Protótipo da função intrínseca usad..................................................................63 Listagem 3 Primeira etapa da redução.................................................................................64
  • 12. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) LISTA DE TABELAS Tabela 1 Evolução da distribuição dos estágios entre CPU e GPU....................................23 Tabela 2 Características dos espaços de memória na arquitetura CUDA séries G80 e G200.........................................................................................................................30 Tabela 3 Passos de quantização.............................................................................................46 Tabela 4 Valores de PF para cada posição...........................................................................47 Tabela 5 Fator de multiplicação............................................................................................47 Tabela 6 Complexidade dos módulos do codificador H.264...............................................56 Tabela 7 Principais características das duas placas utilizadas...........................................66 Tabela 8 Comparação dos tempos de processamento para vídeos 4CIF...........................68 Tabela 9 Comparação dos tempos de processamento vídeo HD........................................68 Tabela 10 Avaliação do algoritmo de busca proposto para 3 Mbps..................................70 Tabela 11 Avaliação do algoritmo de busca proposto para 4 Mbps..................................70 Tabela 12 Avaliação do algoritmo de busca proposto para 5 Mbps..................................71 Tabela 13 Comparação dos desempenho em QCIF.............................................................72 Tabela 14 Comparação dos desempenho em CIF................................................................73 Tabela 15 Comparação dos desempenho em 4CIF..............................................................73 Tabela 16 Comparação dos desempenho em 720p...............................................................74 Tabela 17 Comparação dos desempenho em 1080p.............................................................75
  • 13. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) LISTA DE ABREVIATURAS AMD Advanced Micro Devices ANSI American National Standards Institute API Application Programming Interface AVC Advanced Video Coding CAD Computer Aided Design CIF Common Intermediate Format CPU Central Unit Processing CUDA Compute Unified Device Architecture DC Direct Current DCT Discrete Cosine Transform DSP Digital Signal Processor DVD Digital Versatile Disc FS Full Search GLSL OpenGL Shading Language GPU Graphics Processing Unit GPGPU General Purpose GPU HD High Definition HLSL High Level Shader Language IBM International Business Machines IEC International Electro-technical Commission ISO International Organization for Standardization ITU-T International Telecommunication Union – Telecommunication Standardization Sector JSVM Joint Scalable Video Model JVT Joint Video Team LDS Large Diamond Search LS Logarithmic Search MAE Mean Square Error MSE Mean Square Error
  • 14. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) MC Compensação de movimento ME Estimativa de movimento MF Multiplication Factor MPEG Motion Picture Experts Group PC Personal Computer PCIe Peripheral Component Interconnect Express PF Post-Scaling Factor PGC Professional Graphics Controller QP Quantization Parameter RAM Random Access Memory RGB Red Green Blue SAD Sum of Absolute Differences SD Standard Definition SDS Small Diamond Search SGI Silicon Graphics International SIMD Single Instruction, Multiple Data SIMT Single-Instruction, Multiple-Thread SLI Scalable Link Interface SM Streaming Multiprocessor SP Scalar Processors SSE Streaming SIMD Extensions SVC Scalable Video Coding VRAM Video Random Access Memory
  • 15. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 15 1 INTRODUÇÃO A capacidade de armazenar e transportar vídeo em formato digital tornou as aplicações que fazem uso desta tecnologia parte do cotidiano das pessoas. Atualmente, o vídeo digital está presente em televisores, Digital Versatile Discs (DVDs), videoconferência e sistemas de telemedicina (FUJITSU, 2010). A codificação de vídeo é a técnica essencial que possibilita a utilização de vídeos de forma eficiente. Essa técnica permite a transformação do sinal de vídeo em uma representação comprimida, onde são eliminadas redundâncias, e, com isso reduzir a largura de banda necessária para transportar o vídeo ou o espaço em disco necessário para armazená-lo. O processo de decodificação recupera o sinal de vídeo original ou uma aproximação deste, de forma que possa ser visualizado em sua forma original (RICHARDSON, 2003). A necessidade por técnicas de compressão de vídeo pode ser ilustrada pelo seguinte cenário. Considerando-se, por exemplo, um vídeo com standard definition (SD), que possui 720 x 480 pixeis, e utilizando o sistema de três cores primárias red green blue (RGB), com 8 bits de representação para cada cor e 30 quadros por segundo, seriam necessários aproximadamente 30 MB para armazenar apenas um segundo de vídeo. Dada esta necessidade, surgiram diversas formas de realizar a codificação. Pode-se dizer que a base das técnicas empregadas na maioria dos codificadores atuais foi estabelecida na norma H.261 da International Telecommunication Union – Telecommunication Standardization Sector (ITU-T) definida em 1989, da qual pode-se destacar como algoritmos principais a estimativa de movimento, transformada discreta de cosseno (DCT), quantização linear e codificação de entropia (GHANBARI, 2003). Posteriormente, foi desenvolvido o padrão MPEG-2 pelo Motion Picture Experts Group (MPEG) e também adotado pela ITU-T, como uma norma conjunta das duas entidades e passando a ser chamado H.262/MPEG-2, que tornou-se extremamente popular. O MPEG-2 foi empregado, por exemplo, nos DVDs e em diversos sistemas de televisão digital (MAJOLO, 2010). Este padrão continuou popular ao longo dos anos, sendo largamente empregado ainda nos dias de hoje. A criação de técnicas inovadoras, como a codificação de cenas sintéticas e naturais em um modelo de codificação baseado em objetos independentes e a possibilidade de codificação realizada sobre objetos não necessariamente retangulares, resultou no padrão MPEG-4 (RICHARDSON, 2003).
  • 16. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 16 As entidades MPEG e ITU-T uniram novamente esforços para desenvolver um novo padrão de codificação. Este grupo de trabalho é conhecido como Joint Video Team (JVT). Como resultado surgiu o padrão chamado de Advanced Video Coding (AVC), publicado como a recomendação H.264 da ITU-T e como a parte dez do MPEG-4 (AGOSTINI, 2007). A elaboração do codec H.264 foi feita com o aumento da eficiência da compressão sendo o principal objetivo, resultando em aumentos significativos nas taxas de compressão. No entanto, esta evolução levou inevitavelmente ao aumento dos requisitos de processamento para os dispositivos codificadores e decodificadores (RICHARDSON, 2003). Os algoritmos empregados para codificação de vídeo requerem computação intensa, tornando necessárias técnicas computacionais sofisticadas e o uso de arquiteturas dedicadas que tornem possível a execução destes algoritmos em tempo real. Dentre as soluções que vêm sendo adotadas pode-se destacar a utilização de arquiteturas do tipo Single Instruction, Multiple Data (SIMD), Digital Signal Processor (DSP) e o desenvolvimento de coprocessadores dedicados em hardware (GREENE; TULJAPURKAR, 2007). Uma alternativa recentemente explorada para aumento de desempenho de algoritmos é a utilização de unidades de processamento gráfico, ou Graphics Processing Unit (GPU), como plataformas para processamento de propósito geral. Este conceito, que é conhecido como General Purpose GPU (GPGPU), torna possível explorar o poder de processamento das placas aceleradoras de vídeo em aplicações que não necessariamente façam uso de recursos gráficos (CHEUNG et al., 2010). As GPUs possuem uma arquitetura altamente paralela, capaz de executar a mesma operação em um grande número de elementos ao mesmo tempo. Esta forma de organização é apropriada ao seu objetivo original - processamento de gráficos em três dimensões (3D), mas também pode ser empregada na implementação de algoritmos úteis em diversos outros campos (IKEDA, 2011). Nos últimos anos, foram criadas tecnologias para adequar a GPU ao processamento de propósito geral e facilitar o desenvolvimento de programas que possam fazer uso deste recurso. Um exemplo notável é a arquitetura de computação paralela da NVIDIA denominada Compute Unified Device Architecture (CUDA) (NVIDIA, 2011d). Outros exemplos são: Advanced Micro Devices (AMD) Stream (AMD, 2011), o framework OpenCL (KHRONOS, 2011) e a application programming interface (API) Microsoft Direct Compute (MICROSOFT, 2009). Acredita-se que a utilização de placas de vídeo como ferramenta de auxílio na tarefa de codificação de vídeo seja de grande interesse, dada a variedade de aplicações com vídeo
  • 17. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 17 digital e a grande disseminação destes dispositivos em computadores pessoais. Portanto, este trabalho se propõe a investigar a utilização de GPUs, presentes nas placas de vídeo compatíveis com a tecnologia NVIDIA CUDA, como coprocessadores da Central Unit Processing (CPU) no contexto da codificação de vídeo. Mais especificamente, o objetivo é implementar módulos do codificador H.264 que possuam algoritmos paralelizáveis na GPU, de forma a acelerar a codificação e aliviar a carga da CPU principal. Desta forma, foi explorada a implementação de referência do codificador H.264 de forma a identificar pontos onde a utilização da arquitetura CUDA seja vantajosa. A partir dessa análise e da revisão da literatura, foram definidos dois módulos do codificador a serem trabalhados como estudos de caso: módulo computacional e módulo de estimação de movimento. O primeiro estudo de caso aborda o codificador intraquadros através da implementação dos algoritmos do módulo computacional: transformada discreta de cossenos direta e inversa, transformada de Hadamard direta e inversa, quantização e quantização inversa. Já o segundo estudo de caso aborda a codificação interquadros através da implementação de algoritmos da estimação de movimento: algoritmo de busca e cálculo de similaridade. Para tornar possível a validação e a avaliação dos módulos desenvolvidos foi realizada a integração com o codificador de referência do padrão H.264. Dessa forma, o software de referência serviu como base de comparação em termos do desempenho alcançado e a validação dos resultados será obtida através da comparação dos vídeos comprimidos gerados pelo software original com os vídeos obtidos pela versão paralela. A fim de embasar o desenvolvimento deste trabalho foram pesquisados trabalhos relacionados. Sprandlin et al. (2009) por exemplo analisou a viabilidade de implementar um codificador MPEG-2 na arquitetura CUDA. Chan et al. (2009), Cheung et al. (2010) e Huang, Shen e Wu (2009) por sua vez exploraram diferentes abordagens para acelerar a execução dos algoritmos de estimativa de movimento também utilizando CUDA. Monteiro et al. (2011) realizaram a implementação do algoritmo de busca completa em CUDA, obtendo ganhos de velocidade de 600 vezes. Os trabalhos estudados apontam que a utilização da tecnologia CUDA pode trazer avanços à área de codificação de vídeo, de forma a tornar viável a execução em tempo real de complexas técnicas de codificação em vídeos de alta resolução. O texto desta monografia foi organizado da seguinte forma. O capítulo 2 apresenta uma revisão de literatura acerca da evolução da arquitetura das GPUs que culminou no conceito de GPGPU. O capítulo 3 define os conceitos relacionados à codificação de vídeo, as
  • 18. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 18 características básicas do padrão H.264 e uma descrição dos trabalhos relacionados estudados. O capítulo 4 formaliza a proposta de trabalho que guiou a execução das atividades. O capítulo 5 apresenta os estudos de caso realizados. Por fim, o capítulo 6 apresenta as conclusões obtidas e aponta possíveis trabalhos futuros.
  • 19. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 19 2 UNIDADE DE PROCESSAMENTO GRÁFICO A Unidade de Processamento Gráfico é um processador dedicado à aceleração de aplicações gráficas. A arquitetura das GPUs difere substancialmente das tradicionais CPUs, pois direcionam-se a necessidades específicas, como processamento de dados 3D com ponto flutuante. Sua organização interna torna possível uma intensidade aritmética muito maior, através da execução de diversas operações iguais em dados independentes (OWNEW et al., 2005). Essas características surgiram da necessidade de processar um grande número de pixeis para gerar uma imagem a ser exibida. Como cada pixel é independente dos demais é possível calcular os valores de vários pixeis simultaneamente. Esta arquitetura paralela possibilita portanto a execução de um grande número de operações por unidade de tempo. 2.1 Histórico das GPUs A ideia de se utilizar processadores especificamente para as tarefas relacionadas a vídeo remonta ao ano de 1984 quando a International Business Machines (IBM) lançou a primeira placa de vídeo com microprocessador próprio (Intel 8088) de forma a amenizar a carga da CPU principal. Nesta época, o processador era empregado apenas para gerar os sinais de vídeo, a fim de possibilitar melhores taxas de atualização da tela. Essa solução, conhecida como Professional Graphics Controller (PGC), era destinada a custosos sistemas de Computer Aided Design (CAD) e não se disseminou para o mercado de massa (DUKE; WALL, 1985). Em 1986, a Texas Instruments lançou o processador TMS34010. Este chip, além de possuir uma memória dedicada para vídeo, chamada de Video Random Access Memory (VRAM) e suporte a display, foi um dos primeiros a apresentar um conjunto de instruções voltado ao processamento gráfico (GUTTAG et al., 1988). Entretanto, no final dos anos 80 surgiram as primeiras placas de vídeo compatíveis com a arquitetura IBM-PC (Personal Computer), que possuíam implementações em hardware das primitivas gráficas de duas dimensões (2D) e, por isso, tornaram-se conhecidas como placas aceleradoras 2D (CROW, 2004). No início dos anos 90, a Silicon Graphics International (SGI), que era líder no mercado de gráficos 3D, criou a API OpenGL, que posteriormente tornou-se um padrão mantido por diversas entidades. O surgimento da OpenGL trouxe uma forma uniforme de acesso às diferentes placas gráficas e deixou aos fabricantes a responsabilidade de
  • 20. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 20 desenvolver device drivers para os seus produtos. Posteriormente, a empresa Microsoft lançou o conjunto de APIs DirectX, que inclui a API Direct3D que tornou-se grande competidora da OpenGL. A possibilidade de escrever software utilizando uma API de alto nível compatível com uma grande diversidade de placas de vídeo teve um forte impacto no mercado para aplicativos gráficos (CROW, 2004). No início da década de 90 começavam a se tornar comuns aplicativos com gráficos 3D que faziam uso do poder de processamento da CPU, criando uma demanda crescente por aceleração 3D em hardware. Por volta de 1995, surgiram os primeiros produtos a implementar essa ideia: S3 ViRGE, ATI Rage, Matrox Mystique e 3dfx Voodoo. O passo seguinte à aceleração 3D foi o surgimento das GPUs, que ocorreu por volta de 1998, acrescentando processamento gráfico 3D ao hardware. No entanto, nesse período o processamento gráfico ainda era realizado por funções fixas definidas no projeto da GPU. A partir desse ponto, a evolução pode ser definida em cinco gerações (IKEDA, 2011). 2.1.1 Primeira geração No final da década de 90, haviam três grandes empresas no segmento: NVIDIA, ATI e 3Dfx (com seus respectivos produtos, RIVA TNT2 - NV5, Rage 128 e Voodoo3). Nos dispositivos dessa geração não havia processamento na placa além da rasterização, texturização e geração dos sinais para o monitor. A rasterização consiste na conversão de representações vetoriais de objetos 3D em uma representação matricial, também conhecida como raster. Já a texturização é responsável pela aplicação de uma textura às faces de um objeto tridimensional. A imagem 3D é sintetizada por um conjunto de polígonos (comumente triângulos), resultantes da projeção para um espaço bidimensional (AZEVEDO, 2003). 2.1.2 Segunda geração Em 1999, o lançamento da GeForce 256 (NV10) pela empresa NVIDIA, destacou-se pela introdução do pipeline gráfico, tornando a GPU responsável pela transformação e iluminação dos polígonos, especificados em coordenadas de mundo. Neste período a ATI lançou a família de produtos Radeon R100 com a tecnologia HyperZ, que permitia evitar cálculos desnecessários em pixeis não visíveis na projeção final. O pipeline gráfico é um modelo conceitual composto por estágios que aplicam uma série de algoritmos aos dados processados por uma GPU. Os dados de entrada são um
  • 21. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 21 conjunto de vértices e os respectivos atributos. Após a execução de todos os estágios do pipeline, obtém-se a representação de uma imagem a ser exibida na tela. A adoção dessa arquitetura possibilitou um grande avanço nos jogos e aplicações gráficas em tempo real, pois boa parte das tarefas que antes eram feitas pela CPU foram levadas para o hardware da GPU. Esta arquitetura permitia uma certa flexibilidade ao desenvolvedor, que podia configurar os módulos da GPU (IKEDA, 2011). A empresa 3DFX, por sua vez, lançou a tecnologia Scalable Link Interface (SLI), que permitia a conexão e utilização em paralelo de duas placas de vídeo. Posteriormente, a 3DFX foi adquirida pela NVIDIA, que passou a utilizar esta tecnologia em sua linha de produtos. Neste mesmo período, ATI e NVIDIA tinham produtos com características semelhantes dando início a uma concorrência acirrada (IKEDA, 2011). 2.1.3 Terceira Geração Em 2001, a NVIDIA lançou a primeira GPU programável – GeForce 3 (NV20), que competiu diretamente com a Radeon 8500 (R200) lançada pela ATI. A introdução das técnicas de pixel shading e vertex shading foi a grande evolução desta geração (VIANA, 2009). O pixel shading torna possível desenvolver programas capazes de manipular os pixeis após a rasterização, de forma a criar efeitos na imagem, como por exemplo, rugosidade ou desfoque. Já vertex shading possibilita a criação de programas capazes de manipular a estrutura dos vértices do modelo tridimensional (ou seja, antes de rasterização), para otimizar os modelos 3D ou alterar o modelo dinamicamente. Os programas desenvolvidos com essas duas técnicas são conhecidos como shaders. Ambas as técnicas são utilizadas a fim de obter maior realismo nas imagens sem sobrecarregar a CPU principal, pois os shaders são executados inteiramente pela GPU (ST-LAURENT, 2004). A capacidade de processamento desta geração era limitada, sendo necessário utilizar a linguagem de montagem (assembly) da GPU. Entretanto, a partir desta fase a GPU começou a ser encarada com um hardware vetorial programável (VIANA, 2009). 2.1.4 Quarta geração A quarta geração introduziu o tratamento de variáveis de ponto flutuante e uma maior flexibilidade na utilização de dados de textura. Nesse período, com início por volta de 2003, a
  • 22. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 22 concorrência foi intensa com o lançamento da série FX (NV30) e GeForce 6 pela NVIDIA e da série R300 e X1 pela ATI. Este foi um momento importante na evolução das placas de vídeo, devido a ser a primeira vez na história em que foi possível desenvolver, ainda que precariamente, aplicativos de propósito geral sobre tecnologias de GPU (NVIDIA, 2009). 2.1.5 Quinta geração O ponto marcante das placas dessa geração são as arquiteturas elaboradas para explorar a computação paralela de propósito geral em GPUs. Pode-se dizer, portanto, que somente a partir de meados de 2006 que a computação paralela em hardware gráfico tornou- se de grande interesse no mercado, indo além da comunidade científica (IKEDA, 2011). O conceito de desenvolvimento de programas de propósito geral para GPUs é um dos focos deste trabalho e, portanto, será detalhado a partir da Subseção 2.3. 2.2 Pipeline gráfico tradicional O processo executado por todo o pipeline pode ser dividido em duas etapas principais: processamento de geometria e renderização. A primeira etapa transforma as coordenadas dos objetos de três dimensões em representações de duas dimensões, apropriadas à exibição. A segunda etapa preenche a área entre as coordenadas 2D com pixeis que representam a superfície dos objetos. O estágio de geometria ainda pode ser subdividido em: transformações e iluminação (CROW, 2004). Inicialmente, apenas a renderização era implementada em hardware, por ser uma operação simples e repetitiva, e as outras operações eram executadas pela CPU. Com a evolução no desenvolvimento das GPUs, cada vez mais tarefas foram alocadas às placas de vídeo, a fim de diminuir a carga da CPU (NVIDIA, 1999). A ideia do pipeline é fazer com que cada um desses módulos opere em paralelo, ao invés de tratar um pixel de cada vez. Nas placas de vídeo modernas, o pipeline completo é replicado diversas vezes, de forma a obter maior vazão no processamento. Ao longo dos anos, mais etapas do pipeline foram sendo trazidas da CPU para a GPU, chegando ao cenário atual, onde apenas a lógica da aplicação e as computações da cena são executadas pela CPU principal. A Tabela 1 lista os estágios do pipeline gráfico e a evolução da distribuição dos mesmos entre CPU e GPU.
  • 23. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 23 As características do pipeline delinearam a arquitetura das GPUs. O fato de todos os pixeis necessitarem passar pelos mesmos módulos de execução levou as GPUs a adotarem arquiteturas paralelas. Tabela 1 Evolução da distribuição dos estágios entre CPU e GPU. Estágio 1996 1997 1998 1999 Lógica da aplicação CPU CPU CPU CPU Computações da cena CPU CPU CPU CPU Transformações CPU CPU CPU GPU Iluminação CPU CPU CPU GPU Criação dos triângulos CPU Processador gráfico Processador gráfico GPU Renderização Processador gráfico Processador gráfico Processador gráfico GPU Fonte: NVIDIA, 1999. 2.3 Processamento de propósito geral em GPU O uso da GPU para processamento de propósito geral começou com a utilização de linguagens de shading, como Direct3D High Level Shader Language (HLSL) e OpenGL Shading Language (GLSL). Dessa forma, aplicações em diversas áreas foram aceleradas, no entanto exigindo que todos os algoritmos fossem adaptados para trabalhar com dados expressos em termos de vértices e texturas. Nas primeiras soluções, haviam outras limitações, como a impossibilidade de leituras e escritas em posições aleatórias da memória (NVIDIA, 2009). O uso de chips e APIs gráficas neste contexto revelou um grande potencial na aceleração de algoritmos que possuam uma estrutura passível de paralelização, fazendo uso de hardware padrão presente em um grande número de computadores. O surgimento deste novo segmento resultou na criação de arquiteturas que tornam as GPUs mais apropriadas ao processamento geral e ao desvinculamento de seus ambientes de desenvolvimento das APIs gráficas tradicionais. A primeira arquitetura de GPGPU, também chamada de computação para GPU, foi criada pela empresa NVIDIA e será detalhada a seguir. 2.4 Visão Geral da CUDA CUDA é a arquitetura de computação paralela de propósito geral que faz uso da capacidade de processamento presente nas GPUs da NVIDIA. A arquitetura CUDA provê um modelo de programação escalável baseado em três conceitos centrais: uma hierarquia de grupos de threads, memória compartilhada entre as threads e barreiras de sincronização.
  • 24. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 24 Esses conceitos são expostos ao desenvolvedor como um conjunto de extensões à linguagem C (NVIDIA, 2011a). A arquitetura CUDA definiu duas alterações principais na organização das GPUs: a unificação dos shaders (vertex e pixel shaders) e a criação de memória compartilhada. O componente resultante da união dos shaders é chamado stream processor (SP). Essas alterações transformaram as GPUs em dispositivos adequados ao processamento de propósito geral (HUANG; SHEN; WU, 2009). A Figura 1 ilustra a arquitetura unificada dos shaders em contraste aos shaders tradicionais. A unificação dos shaders transformou as unidades especializadas em processamento de vértices ou pixeis, por exemplo, em unidades de computação genérica interconectadas por um escalonador dinâmico que divide a carga de processamento entre as diversas unidades que compõe a GPU. Dessa forma, a utilização dos recursos de hardware foi flexibilizada. Figura 1 Shader tradicional x shader unificado, adaptado de (IKEDA, 2011). Os grupos de threads são escalonados para execução em um dos núcleos, sequencialmente ou simultaneamente, sem que seja necessário explicitar em qual núcleo o bloco será alocado. Desta forma, um mesmo programa poderá ser executado em GPUs com diferentes quantidade de núcleos e, ainda assim, fará uso de todo o poder de computação disponível. A Figura 2 ilustra a execução de um mesmo programa em duas placas de vídeo, a da esquerda possui uma GPU com dois núcleos e a da direita com quatro núcleos. O programa em questão foi parametrizado para execução com oito blocos de threads. No primeiro caso, cada núcleo fica responsável pela execução de quatro blocos. Já no segundo caso, os oito
  • 25. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 25 blocos são divididos entre os quatro núcleos disponíveis. Esse escalonamento é realizado internamente pela GPU e não é determinado pelo código da aplicação. Dessa forma, a arquitetura provê um ambiente escalável para a execução dos programas. Figura 2 Escalabilidade da arquitetura CUDA, adaptada de (NVIDIA, 2011a). A arquitetura CUDA já sofreu algumas alterações desde a sua concepção inicial. Algumas características foram sendo implementadas ao longo do tempo, a fim de aprimorar o desempenho das GPUs. Portanto, diferentes placas podem conter um conjunto de características diferentes. A fim de identificar as características presentes em um determinado dispositivo, todas as placas são categorizadas em compute capabilities identificados por um versionamento numérico. Os manuais da NVIDIA apresentam as características do hardware de acordo com essa numeração. Por exemplo, um determinada funcionalidade pode estar presente apenas nos dispositivos de compute capability 1.2. Se a funcionalidade for descrita para o compute capability 2.x, significa que todos as placas com versão 2 suportam-na, independentemente do outro algarismo. 2.5 Arquitetura de hardware As placas de vídeo compatíveis com a tecnologia CUDA possuem um conjunto escalável de multiprocessadores, que são chamados streaming multiprocessors (SMs). Os SMs são compostos por uma série de processadores escalares (scalar processors – SP), uma unidade de instrução multi thread e memória compartilhada. Os blocos de threads criados
  • 26. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 26 pelo kernel são escalonados para execução em SMs com capacidade ociosa. As threads dentro de um mesmo bloco são executadas concorrentemente, pois cada thread é mapeada em um SP, com seus próprios registradores. A NVIDIA chamou essa arquitetura de Single- Instruction, Multiple-Thread (SIMT) (NVIDIA, 2011a). O escalonador de threads separa-as em grupos, chamados warps. A cada ciclo de instrução um warp é selecionado para execução, então a mesma instrução é executada em todas as threads ativas neste warp (NVIDIA, 2011c). Apesar de todas as threads começaram a execução no mesmo ponto do código, há a possibilidade de que haja ramificação na execução. Neste caso, nem todas as threads estarão ativas no mesmo momento, resultando na serialização da execução. Portanto, para que seja alcançada eficiência máxima na execução paralela das threads é necessário que não hajam ramificações no fluxo de execução (branch divergence) dentro de um mesmo warp (HAN; ABDELRAHMAN , 2011). A Figura 3 apresenta três casos típicos onde ocorre a divergência no fluxo de execução. Na situação (a), o incremento executado dentro do bloco condicional faz com que os SPs destinados às threads que não executam o incremento fiquem inativos por alguns ciclos. O cenário (b) pode ser interpretado como duas instruções condicionais na sequência, com as mesmas implicações do exemplo anterior. No terceiro caso, o número de iterações executadas no laço pode diferir para cada thread. A diferença no número de iterações do laço para cada thread resultará que os SPs alocados para as threads com menor número de iterações ficarão inativos, enquanto os outros SPs executam as últimas iterações para as outras threads do mesmo warp (HAN; ABDELRAHMAN , 2011). Figura 3 Cenários comuns de branch divergence, adaptada de (HAN; ABDELRAHMAN , 2011). Esta arquitetura criada pela NVIDIA é similar às arquiteturas SIMD presentes em diversas CPUs, no entanto, existem diferenças importantes (REN et al. 2010). Nas arquiteturas SIMD, diversos elementos de dados são salvos em um registrador. A largura dos
  • 27. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 27 registradores, que determina o nível de paralelismo em nível de instrução, é exposta ao software. Na arquitetura SIMT, por outro lado, o paralelismo se dá pela execução de diversas threads que podem executar trechos de código distintos (NVIDIA, 2011c). O comportamento específico da arquitetura SIMT pode ser ignorado pelo programador a fim de obter-se uma implementação meramente funcional de determinado algoritmo, mas através da adequação da implementação às características próprias do hardware (GPU) é possível obter maiores ganhos de desempenho. Analogamente, nas arquiteturas tradicionais é possível ignorar a largura das linhas de cache e, ainda assim, obter implementações funcionais. No entanto, quando almeja-se obter picos de desempenho essa informação precisa ser considerada (NVIDIA, 2011c). 2.6 Modelo de programação O modelo de programação do CUDA permite que o programador crie um grande número de threads que executarão código escalar, ou seja, cada thread analisada isoladamente contém código que será executado sequencialmente, sem nenhum nível de paralelismo. O modelo de programação criado pela NVIDIA possibilita aos desenvolvedores criar aplicações paralelas com certo grau de facilidade, mesmo aqueles que não possuem grande familiaridade com arquiteturas paralelas (BAKHODA et al., 2009). As características do modelo de programação são expostas ao programador através de uma extensão da linguagem de programação ANSI C (American National Standards Institute). Os três conceitos chave desse modelo são descritos nas subseções seguintes: kernel, hierarquia de threads e hierarquia de memória. 2.6.1 Função Kernel A extensão da linguagem C criada pela NVIDIA possibilita a criação de funções que serão executadas na GPU. Para tanto, existem três palavras-chave: __global__, __device__ e __host__. A primeira delas específica uma função que será executada na GPU, mas será chamada da CPU. Uma função com esta característica é chamada de kernel e cabe ao programador especificar quantas vezes esta função deve ser executada paralelamente. Para tanto, na chamada do kernel é definido o tamanho do grid, ou seja, a quantidade de blocos de threads (NVIDIA, 2011). Na Listagem 1, a linha um contém o protótipo com a declaração de um kernel e a linha dois a chamada do kernel, com a especificação dos parâmetros de execução.
  • 28. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 28 1 __global__ kernel_function(char *buffer); 2 kernel_function<<<dimGrid,dimBlock,0,stream>>>(buffer); Listagem 1 Declaração e chamada de um kernel. A palavra-chave __device__, por outro lado, declara uma função que será executada pela GPU e poderá ser invocada somente por código executado na própria GPU. Já a palavra- chave __host__ declara funções convencionais, ou seja, que são chamadas e executadas pela CPU. __host__ é o qualificador padrão na declaração de funções, portanto, não precisa estar explícito no protótipo da função. 2.6.2 Hierarquia de threads A organização das threads se dá na forma de blocos com uma, duas ou três dimensões. Esse arranjo torna simples a execução de cálculos em elementos de vetores, matrizes ou volumes. A identificação da thread que está sendo executada é possível através dos índices que identificam a posição da thread dentro do bloco. Os índices são disponibilizados ao programador através da variável tridimensional threadIdx que contém três campos de inteiros sem sinal: x, y, z. Os blocos contém grupos de threads que são organizados em um grid, que também pode ter até três dimensões. O tamanho do grid é determinado a partir da quantidade de dados a serem manipulados ou pela quantidade de processadores. Os blocos são identificados dentro do grid de mesma forma que as threads dentro de um bloco. Para tanto, existe a variável blockIdx, do tipo uint3. Já o tamanho dos blocos, ou seja, a quantidade de threads pode ser obtido através da variável blockDim. As variáveis threadIdx, blockIdx e blockDim são chamadas built-in, ou seja, elas são automaticamente acessíveis dentro do kernel, mesmo sem terem sido explicitamente declaradas. A execução dos blocos de threads poderá ocorrer em qualquer ordem, serialmente ou paralelamente. Portanto, a operação executada em um bloco não pode depender de resultados obtidos em outros blocos. Essa característica possibilita a escalabilidade do código, de forma a utilizar diferentes quantidades de núcleos de processamento disponíveis (NVIDIA, 2011a). As threads que residem no mesmo bloco são executadas no mesmo SM podendo cooperar entre si através do compartilhamento de dados (pela memória compartilhada) e sincronização da execução com funções intrínsecas que servem como barreiras na execução,
  • 29. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 29 de forma que a execução prossiga apenas quando todas as threads tenham finalizado a execução de uma determinada sequência de instruções. AFigura 4 ilustra a forma de organização hierárquica das threads. Figura 4 Organização das threads, adaptada de (NVIDIA, 2011a) 2.6.3 Hierarquia de memória CUDA expõe seu modelo de memória, que é composto por diferentes espaços de memória, tornando necessário ao desenvolvedor conhecer a arquitetura e definir onde cada conjunto de dados da aplicação deve residir. A correta utilização das diferentes memórias presentes na placa de vídeo, geralmente, tem implicação direta no desempenho do aplicativo. A Tabela 2 apresenta um visão geral das memórias disponíveis na arquitetura CUDA. Pode-se observar que as memórias mais abundantes possuem uma latência elevada por estarem localizadas fora do chip. A quinta coluna da tabela define que as memórias de constantes e de texturas possuem acesso somente de leitura, ou seja, é possível escrever nestas memórias apenas através de código executado na CPU. A subseção seguinte apresenta um detalhamento de cada uma dessas memórias. O fluxo dos dados na aplicação geralmente segue o seguinte padrão: inicialmente os dados são copiados da memória RAM (random access memory) do computador (host) para a memória global da GPU (device), através do barramento Peripheral Component Interconnect Express (PCIe). Após essa cópia os dados já estão acessíveis às threads, no entanto, é comum realizar a transferência da memória global para a memória compartilhada de um SM, de forma a minimizar a quantidade de acessos à memória global. Dessa forma, a memória compartilhada é utilizada como um cache entre a memória global e o aplicativo, para reduzir os efeitos da alta latência no acesso a memória global.
  • 30. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 30 Tabela 2 Características dos espaços de memória na arquitetura CUDA séries G80 e G200. Memória Localização Tamanho Latência Somente leitura Escopo Registradores SM até 64 kB por SM ~ 0 ciclos não thread Local Placa de vídeo depende da global 400 – 600 ciclos não thread Compartilhada SM1 16 kB por SM >= 4 ciclos não Todas as threads em um bloco Global Placa de vídeo até 1024 MB 400 – 600 ciclos não Todas as threads + host Constante Placa de vídeo2 64 kB 0 – 600 ciclos sim Todas as threads + host Textura Placa de vídeo3 depende da global 0 – 600 ciclos sim Todas as threads + host Fonte: Adaptado de NVIDIA, 2011b e Conrad, 2010. Após esta etapa, as threads manipulam os dados que estão na memória compartilhada, utilizando os registradores para armazenar variáveis de controle e resultados intermediários. Ao final do processamento, cada thread escreve o resultado da sua execução na memória global, a fim de tornar acessível ao host os resultados obtidos. Por fim, o host copia os resultados que estão na memória global de volta para a memória do computador. Figura 5 Fluxo típico de uma aplicação CUDA. 1 Esta memória possui cache nos dispositivos 2.x. 2 Esta memória possui cache em todos os dispositivos. 3 Esta memória possui cache em todos os dispositivos.
  • 31. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 31 2.7 Detalhamento dos espaços de memória A seguir serão apresentados os detalhes relevantes de cada memória. 2.7.1 Registradores e memória local Os registradores são utilizados para armazenar as variáveis automáticas (também chamadas de variáveis locais). Se não houver espaço suficiente, o compilador alocará as variáveis na memória local. Dessa forma, estruturas ou vetores (automáticos) grandes possivelmente serão alocados na memória local. Como a memória local está localizada fora do chip e não possui cache (em dispositivos 1.x), apresenta tempo acesso elevado (NVIDIA, 2011b). A memória local é apenas uma abstração sobre a memória global, com escopo limitado a cada thread (IKEDA, 2011). Portanto, a quantidade e o tamanho das variáveis automáticas podem influenciar diretamente o desempenho do aplicativo. 2.7.2 Memória compartilhada A memória compartilhada está localizada dentro de cada multiprocessador, por isso, possui latência cerca de cem vezes menor do que a memória global ou local, porém o tamanho total desta memória é reduzido (NVIDIA, 2011b). A memória compartilhada pode ser utilizada como uma memória cache explicitamente gerenciada, ou seja, cabe ao programador utilizar esse recurso para minimizar a quantidade de acessos a memória global. A memória compartilhada é organizada em bancos, ou seja, módulos que podem ser acessados simultaneamente, a fim de obter uma alta largura de banda. Essa arquitetura permite que diversas requisições, que acessem endereços localizados em diferentes bancos, possam ser atendidas ao mesmo tempo. Por outro lado, se uma requisição de acesso a memória contiver acessos em endereços localizados no mesmo banco haverá um conflito de acesso. Nessa situação, os acessos serão separados em requisições consecutivas separadas para que não contenham nenhum conflito (NVIDIA, 2011a). A ocorrência de conflitos se dá quando mais de uma thread pertencente ao mesmo half-warp4 solicitam acesso a posições de memória que localizam-se em um mesmo banco. Há uma exceção no caso de todas as threads de um half-warp executarem uma leitura no mesmo endereço, neste caso o conteúdo lido é disponibilizado para todas as threads através de um broadcast. Em dispositivos com compute capability 2.x há também a possibilidade de 4 Half-warp é um grupo de threads, com metade do tamanho de um warp. Em dispositivos com compute capability 1.x, o half-warp é menor unidade escalonada pelo SM. Já em dispositivos com compute capability 2.x a menor unidade escalonada é o próprio warp.
  • 32. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 32 multicast, onde o conteúdo lido é disponibilizado para um grupo de threads, mas não necessariamente para todas (NVIDIA, 2011b). 2.7.3 Memória global A memória global está localizada na placa de vídeo, no entanto, não sendo integrada ao chip da GPU, possui alta latência no acesso. Esta memória pode ser acessada através de transações de 32, 64 ou 128 bytes, alinhadas. Isto é, o endereço do primeiro elemento manipulado precisa ser um múltiplo do tamanho do segmento (NVIDIA, 2011a). As requisições de acesso à memória global efetuadas por um half-warp (em dispositivos com compute capability 1.x) ou por um warp (em dispositivos com compute capability 2.x) são combinadas resultando na menor quantidade de transações possível, que obedeça as regras de alinhamento impostas pela arquitetura de hardware (NVIDIA, 2011b). As regras que definem o agrupamento dos acessos à memória global em transações variam entre dispositivos com diferentes compute capabilities. Inicialmente, a arquitetura da GPU impunha restrições mais severas no padrão de acesso que resultava na combinação de vários acessos em uma transação. Entretanto, as placas de vídeo mais recentes, que possuem compute capability 2.x, apresentam avanços nesse quesito. A Figura 6 ilustra padrões de acesso que permitem o acesso coalescido, ou seja, o acesso a várias posições de memória em apenas uma transação. Desta forma, os efeitos da latência de acesso são diluídos. A figura (a) exemplifica o acesso coalescido a variáveis float de quatro bytes. A figura (b) ilustra o acesso coalescido por um warp divergente, ou seja, neste caso nem todas as threads acessam as respectivas variáveis. Figura 6 Padrões de acesso coalescido (CONRAD, 2010). A Figura 7, por outro lado, exemplifica padrões de acesso que não possibilitam o acesso coalescido. A figura (a) possui um padrão de acesso não sequencial, ou seja, as
  • 33. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 33 threads não acessam as suas respectivas posições. Já a figura (b) apresenta um padrão de acesso sequencial. No entanto, o acesso é desalinhado o que impossibilita o coalescing. Figura 7 Acesso não coalescido (CONRAD, 2010). Uma característica dos dispositivos com compute capability 2.x que pode amenizar o impacto da alta latência no acesso a memória global é a presença de dois níveis de cache (cache L1 e L2) entre o SM e a memória global. O cache L1 é composto de linhas de 128 bytes que mapeiam segmentos alinhados na memória global. Já o cache L2 é composto por linhas de 32 bytes. O tamanho das linhas determinam o tamanho da transação que será usada para acessar os dados através do cache. Em certas circunstâncias pode ser vantajoso utilizar apenas o cache L2, por exemplo, quando os acessos são dispersos na memória a utilização de cache com linhas mais estreitas resulta numa menor quantidade de leituras ou escritas desnecessárias. Por esse motivo, o compilador possui um parâmetro que permite definir se os acessos a memória global utilizarão os caches L1 e L2 ou apenas o L2 (NVIDIA, 2011a). 2.7.4 Memória de textura e superfície A memória de textura ou superfície está localizada na memória da placa de vídeo e possui cache otimizado para acesso a dados que apresentem localidade espacial em duas dimensões, ou seja, dados localizados em posições próximas. Além disso, esse espaço de memória é projetado de forma a obter fluxos de leitura com latência constante. Dessa forma, uma leitura do cache reduz a largura de banda demandada, mas a latência se mantém constante (NVIDIA, 2011a).
  • 34. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 34 Quando um warp necessita de um dado que está presente no cache há um ganho significativo no tempo de leitura, caso o dado não esteja disponível no cache o tempo de acesso será o mesmo de uma leitura na memória global convencional. A memória de textura pode ser escrita a partir do host, mas do ponto de vista da GPU é uma memória somente de leitura. 2.7.5 Memória de constantes A memória de constantes está localizada no dispositivo e possui memória cache. Possui acesso somente de leitura pela GPU. Além de ser usada explicitamente, em dispositivos com compute capability 2.x esta memória pode ser utilizada pelo compilador através de instruções específicas (NVIDIA, 2011a).
  • 35. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 35 3 CODIFICAÇÃO DE VÍDEO Um codificador de vídeo transforma o vídeo de sua forma original em uma representação comprimida, de forma a permitir uma utilização mais eficiente de recursos como largura de banda (nos sistemas de comunicação) e espaço (nos sistemas de armazenamento). A utilização do vídeo codificado requer um decodificador, que é o sistema capaz de realizar a conversão inversa, a fim de obter o vídeo na sua forma natural. O par codificador/decodificador é o que se chama codec (RICHARDSON, 2010). 3.1 Vídeo digital O vídeo digital baseia-se na utilização de dados amostrados temporalmente e espacialmente. A partir da amostragem, obtém-se uma matriz retangular com valores que representam a informação visual que é composta por três componentes, devido às características fisiológicas do sistema visual humano (GONZALEZ, 2000). A forma de representação das três componentes é chamado espaço de cores. Existem diversos espaços empregados em diferentes aplicações. Os monitores de vídeo utilizam o RGB, baseado nas componentes vermelha, verde e azul. Já os sistemas de televisão e os codificadores de vídeo utilizam o YCbCr, que define a luminância (Y), a crominância azul (Cb) e a crominância vermelha (Cr) (SHI; SUN, 2008). A utilização do espaço de cores YCbCr associado com a subamostragem das crominâncias é realizada através de padrões de amostragem bem estabelecidos, como 4:4:4, 4:2:2 e 4:2:0. Na amostragem 4:4:4 as crominâncias são mantidas intactas, portanto, todos os pixeis possuem uma amostra de cada componente (Y, Cb e Cr). No caso 4:2:2, a amostragem das crominâncias possui a metade da resolução no sentido horizontal, ou seja, para cada quatro amostras de luminância existem duas amostras de cada crominância. Por fim, o formato 4:2:0 reduz a resolução tanto horizontalmente quanto verticalmente, ou seja, para cada quatro amostras de luminância é utilizada apenas uma amostra de cada crominância, obtendo 50% menos bits na representação, se comparado com o formato 4:4:4 (RICHARDSON, 2003). A subamostragem é amplamente utilizada nos codificadores atuais, devido à redução do espaço de informação ocupado por esta técnica. Por exemplo, um vídeo em formato YCbCr 4:2:0 obtém uma taxa de compressão de 50% em relação a um vídeo em RGB ou YCbCr 4:4:4 com perdas de qualidade pouco significativas (AGOSTINI, 2007).
  • 36. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 36 3.2 Compressão de vídeo As técnicas de compressão com perdas são amplamente utilizadas nos codificadores de vídeo atuais, de forma a explorar as limitações do sistema de visão humano. Além disso, o olho humano possui sensibilidade diferenciada em relação a diferentes componentes ou características da imagem (GONZALEZ, 2000). Entretanto, a representação digital de vídeos apresenta uma enorme quantidade de dados redundantes que possibilita a utilização de técnicas de codificação preditiva sem perdas. Os altos níveis de compactação obtidos pelos codecs atuais são possíveis com a combinação destas técnicas (com e sem perdas) (DINIZ, 2009). Um codificador de vídeo, de forma geral, é composto por três partes principais: módulo temporal, módulo espacial e codificador de entropia. Cada um desses módulos é responsável por remover um tipo de redundância presente no vídeo (AGOSTINI, 2007): a) Redundância Espacial: devida à correlação existente entre os pixeis ao longo de um quadro (por isso, chamada intraquadro). A remoção dessa redundância é realizada no domínio espacial e no domínio das frequências, pela predição intraquadro e quantização, respectivamente. A quantização é uma operação irreversível, pois gera perdas na codificação. No entanto, as perdas tendem a ser pouco significativas na qualidade visual da imagem. b) Redundância Temporal: se deve à correlação existente entre os diversos quadros (por isso, chamada interquadro) temporalmente adjacentes. Essas redundância pode ser visualizada como uma dimensão adicional da redundância espacial (GONZALEZ, 2000). Esta correlação temporal é tratada pelo módulos de estimativa e compensação de movimento. c) Redundância Entrópica: relaciona-se com a probabilidade de ocorrência de determinados símbolos, sendo que quanto maior a probabilidade de ocorrência de um determinado símbolo, menos informação estará sendo codificada através dele. A codificação de entropia utiliza algoritmos de compressão sem perdas objetivando a codificação da maior quantidade de informação possível por símbolo. A entropia é a medida da quantidade média de informação codificada por símbolo (SHI; SUN, 2007).
  • 37. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 37 3.3 Introdução ao H.264 H.264 é um padrão internacional de codificação de vídeo para a indústria. É composto por um documento publicado pela ITU-T e ISO/IEC (como sendo a parte 10 do MPEG-4) que possui instruções que definem o formato do vídeo codificado. Além disso, é definido, em detalhes, o funcionamento de um decodificador capaz de decodificar o formato especificado (ITU-T, 2003). Assim como em outros padrões de codificação, não são especificados os detalhes do codificador. A única restrição imposta na implementação do codificador, é que ele precisa gerar um bitstream (fluxo de vídeo codificado) conforme a especificação, de forma que possa ser decodificado corretamente por qualquer implementação do decodificador (RICHARDSON, 2003). O H.264 define um conjunto de técnicas e ferramentas de compressão, o codificador pode optar por qual desses itens irá fazer uso. O padrão H.264 foi originalmente publicado em 2003 e sofreu diversas revisões e atualizações desde então. Os conceitos básicos deste codec são os mesmos presentes no MPEG-2 e MPEG-4 Visual, no entanto, os avanços sugeridos proporcionam um aumento potencial na eficiência, qualidade e flexibilidade da compressão (RICHARDSON, 2010). 3.4 Descrição do codec H.264 O codificador possui dois caminhos por onde os dados fluem: o caminho direto, através do qual é gerado a sequência de bytes que representa o vídeo codificado e o caminho de reconstrução do vídeo, através do qual o codificador monta os quadros decodificados a serem usados como referência. Inicialmente, cada macrobloco5 do quadro original a ser codificado é subtraído de um macrobloco de referência obtido pela predição intraquadro ou pela compensação/estimativa de movimento. Os macroblocos de referência utilizados são oriundos de quadros reconstruídos pelo caminho de reconstrução, que executa as operações identicamente a um decodificador (RICHARDSON, 2003). Os macroblocos de diferenças (geralmente chamados de macroblocos de resíduos) são processados pelos módulos de transformadas e quantização. Os coeficientes quantizados e as informações de controle, que indicam as decisões tomadas pelo codificador, são repassadas ao codificador de entropia que irá reduzir o nível de redundância entrópica do fluxo de bits de saída (bitstream). Por fim, o vídeo codificado será colocado dentro de “pacotes” 5 Macrobloco é um bloco de 16x16 pixeis.
  • 38. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 38 padronizados, referenciados como NAL (Network Abstraction Layer) (RICHARDSON, 2003). As técnicas de compressão baseadas em predição de blocos da imagem fazem uso de blocos da vizinhança (temporal ou espacial) que foram codificados anteriormente ao bloco atual. Tanto o codificador quanto o decodificador executam o procedimento de compensação, de forma que o codificador utilize como quadro de referência o mesmo resultado que será obtido pelo decodificador. Portanto, o resultado quantizado será processado pelo bloco de quantização inversa e transformadas inversas. O resultado desta etapa será somado ao resultado da predição intraquadro ou interquadro e filtrado (para diminuir os efeitos do particionamento da imagem em blocos) e então formará a próxima imagem de referência, ou seja, uma versão decodificada do bloco original (RICHARDSON, 2003). A Figura 8 apresenta os blocos constituintes do codificador H.264. Figura 8 Estrutura do codificador H.264 (REDIESS, 2006). 3.4.1 Predição intraquadro A predição intraquadro tem por objetivo diminuir a redundância espacial dentro um quadro. Sua característica principal é permitir a compressão de dados de cada quadro de forma auto contida, ou seja, cada quadro da sequência de vídeo pode ser processado de forma independente de todos os demais. Este procedimento é aplicado a todos elementos dos macroblocos no domínio espacial (AGOSTINI, 2007). O padrão H.264 define a aplicação da predição intraquadro nos componentes de luminância e crominância dos macroblocos I (Intra), resultando em macroblocos preditos com base em amostras reconstruídas, ou seja, que já percorreram todo o caminho de reconstrução
  • 39. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 39 do codificador. O resultado desta predição é subtraído do macrobloco original a fim de gerar um macrobloco de resíduos a serem codificados. Segundo a norma H.264, existem dois tipos de blocos I: de tamanho 4x4 e 16x16. No primeiro caso o conjunto de 16x16 amostras é processado separadamente em blocos de 4x4. Já no segundo caso, o macrobloco é tratado sem divisões. Para cara tipo de macrobloco I, existem vários modos de predição que visam atacar determinados padrões espaciais no quadro de vídeo. Por exemplo, as Figuras 9 e 10, apresentam os quatro modos de predição para macroblocos I 16x16 e os nove modos de predição para macroblocos I 4x4, respectivamente (RICHARDSON, 2003). Figura 9 Modos de predição para blocos 16x16 de luminância. (AGOSTINI, 2007) As crominâncias são processadas em blocos 8x8 e existem quatro modos de predição possíveis. No entanto, as duas crominâncias sempre utilizam o mesmo modo (RICHARDSON, 2003). A decisão de qual modo de predição será empregado em cada macrobloco fica a cargo do codificador. Existem duas abordagens para a tomada desta decisão: algoritmos de busca completa (que calculam todos os modos possíveis a fim de encontrar qual fornece a melhor eficiência na compressão) e algoritmos rápidos (que baseiam-se em alguma heurística, usando informação do vídeo a ser codificado, de forma a diminuir a complexidade da decisão) (AGOSTINI, 2007).
  • 40. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 40 Figura 10 Modos de predição para blocos 4x4 de luminância (AGOSTINI, 2007). 3.4.2 Transformadas diretas e inversas A codificação por transformadas é uma técnica de compressão que explora a correlação entre os pixeis de uma imagem, sendo empregada tanto em codificação de imagens quanto codificação de vídeo. Este estágio do codificador converte blocos da imagem de entrada ou de resíduos da predição em outro domínio. O domínio para o qual os dados de entrada são convertidos deve conter a informação original separada em componentes descorrelacionadas e com a maior parte da energia do sinal concentrada em um pequeno número de componentes. Além disso, é necessário que a transformada seja reversível, de forma que seja possível voltar à representação original. A transformada adotada na maior parte dos codecs é a DCT bidimensional (SHI; SUN, 2008). O padrão H.264 define a utilização de duas transformadas: DCT e Transformada de Hadamard. O codificador H.264 transforma e quantiza os blocos de coeficientes residuais. A transformada utilizada é uma versão aproximada da DCT, chamada core transform. Após esta etapa, em certos casos, é empregada a Transformada de Hadamard aos coeficientes DC6 obtidos na etapa anterior (RICHARDSON, 2003). As seções seguintes apresentarão os detalhes de cada uma dessas transformadas. 6 Coeficientes DC são aqueles que possuem frequência zero.
  • 41. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 41 3.4.2.1 Transformada discreta de cossenos A DCT é uma transformada derivada da Transformada de Fourier cujo objetivo é converter um bloco de dados de entrada para o domínio das frequências. A equação 1 define a DCT (RICHARDSON, 2003). Y =A· X · A T (1) Onde Y é a matriz de saída X é a matriz de entrada A é a matriz de coeficientes da transformada AT é a matriz A transposta A matriz A é definida pela Equação 2. Aij=C i· cos2j1·i · 2n (2) Onde Ci=0=  1 n  (3) Ci≠0=  2 n  (4) Onde i e j representam a posição do elemento na matriz (linha e coluna, respectivamente) e n representa o número de linhas ou colunas do bloco. A partir das Equações 2, 3 e 4 obtém-se a seguinte matriz de coeficientes para aplicar a transformada em blocos 4x4: A= [ 1 2 ·cos0 1 2 ·cos0 1 2 ·cos0 1 2 ·cos0  1 2 ·cos  8  1 2 ·cos 3· 8  1 2 ·cos 5· 8  1 2 ·cos 7· 8  1 2 ·cos 2· 8  1 2 ·cos 6· 8  1 2 ·cos 10· 8  1 2 ·cos 14· 8  1 2 ·cos 3· 8  1 2 ·cos 9· 8  1 2 ·cos 15· 8  1 2 ·cos 21· 8 ] (5) A Figura 11 exemplifica o funcionamento desta transformada. É possível notar que o bloco resultante (b) possui as componentes mais significativas concentradas na parte superior esquerda do bloco.
  • 42. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 42 Figura 11 Bloco de entrada (a) e resultado da DCT (b) (RICHARDSON, 2003). Como pode-se observar, implementações dessa transformada requerem o uso de aproximações de fatores irracionais. Se forem adotadas diferentes aproximações no codificador e no decodificador, pode haver uma certa discrepância entre predições usadas como referência, resultando distorção na saída do processo de decodificação. Padronizações anteriores, como o MPEG-2 ou MPEG-4 adotaram diferentes medidas para minimizar o impacto dessas aproximações. No entanto, o H.264 (e outros codecs recentes) abordaram esse problema definindo um algoritmo adequado à implementação com aritmética inteira com precisão limitada, de forma a eliminar a necessidade da utilização de valores aproximados. Além disso, a implementação das transformadas em aritmética inteira contribui para a diminuição do custo computacional das transformações (HUSEMANN et al., 2010). A matriz da transformada definida em 5 pode ser reescrita da seguinte forma: A= [ a a a a b c −c −b a −a −a a c −b b −c ] (6) Onde a= 1 2 (7) b=  1 2 ·cos  8  (8) c=  1 2 ·cos 3· 8 (9) Considerando-se as definições 1, 6, 7, 8 e 9 obtém-se:
  • 43. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 43 Y =A· X · A T = [ a a a a b c −c −b a −a −a a c −b b −c ]· X · [ a b a c a c −a −b a −c −a b a −b a −c ] (10) que pode ser fatorada em: Y =A· X · A T =C · X ·C T ⊙E (11) Y = [ 1 1 1 1 2 1 −1 −2 1 −1 −1 1 1 −2 2 −1 ]· [ 1 2 1 1 1 1 −1 −2 1 −1 −1 2 1 −2 1 −1 ]⊙ [ a 2 ab 2 a 2 ab 2 ab 2 b 2 4 ab 2 b² 4 a 2 ab 2 a² ab 2 ab 2 b² 4 ab 2 b² 4 ] (12) Onde ⊙ significa que cada elemento da matriz C · X · CT é multiplicado pelo elemento correspondente na matriz E. Essa multiplicação ponto-a-ponto não é efetivamente calculada na implementação da DCT, no entanto, estes fatores de escala são compensados durante a quantização. Os fatores a e b da matriz E são aproximados para simplificar a implementação. a= 1 2 (13) b=  2 5  (14) A DCT inversa é necessária para transformar os dados para o seu domínio original, tanto no decodificador quanto no laço de realimentação do codificador. A DCT inversa é definida pela Equação 15. X =A T ·Y · A (15) Onde X é a matriz recuperada Y é a matriz transformada A é a matriz de coeficientes da transformada AT é a matriz A transposta
  • 44. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 44 As mesmas considerações feitas na transformada direta são aplicadas à transformada inversa, de forma a obter a operação inversa equivalente, resultando na Equação 16. A multiplicação ponto-a-ponto, analogamente, será compensada na quantização inversa. X =A T · X · A= [ 1 1 1 1 2 1 1 2 −1 −1 1 − 1 2  −1 1 1 −1 1 − 1 2  ]· X · [ 1 1 1 1 1 1 2 − 1 2  −1 1 −1 −1 1 1 2 −1 1 − 1 2 ] (16) 3.4.2.2 Transformada de Hadamard O padrão H.264 define a aplicação da transformada de Hadamard aos coeficientes DC dos blocos após o cálculo da DCT, de forma aumentar a compressão em áreas homogêneas (RICHARDSON, 2003). Por exemplo, um macrobloco de luminâncias (16 blocos de 4x4 amostras) resulta em um bloco 4x4 de componentes DC a serem processadas pela transformada de Hadamard. No caso de um macrobloco de crominâncias, o bloco de componentes DC é 2x2, devido à utilização de subamostragem nas crominâncias. A Figura 12 destaca os componentes DC dentro dos macroblocos de crominância (a) e luminância (b). Figura 12 Macroblocos de crominância e luminância com componentes DC destacados (MAJOLO, 2010). A definição matricial da transformada de Hadamard, aplicada às amostras de luminância, é apresentada na Equação 17.
  • 45. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 45 Y L= 1 2 · [ 1 1 1 1 1 1 −1 −1 1 −1 −1 1 1 −1 1 −1 ]· X L · [ 1 1 1 1 1 1 −1 −1 1 −1 −1 1 1 −1 1 −1 ] (17) Onde XL é matriz 4x4 dos coeficientes DC resultantes da execução da DCT em um bloco de 16x16 luminâncias; YL é a matriz com os resultados obtidos pela transformada de Hadamard. Quando aplicada às amostras de crominâncias, a transformada é definida pela Equação 18. Y L=[1 1 1 −1]· XC ·[1 1 1 −1] (18) Onde XC é a matriz com os valores DC resultantes da DCT aplicada às crominâncias YL é a matriz que contém o resultado da transformada. A equação da transformada inversa de Hadamard (para blocos 4x4 de luminâncias) é obtida através da manipulação da Equação 17, resultando em: X L= 1 8 · [ 1 1 1 1 1 1 −1 −1 1 −1 −1 1 1 −1 1 −1 ]·Y L · [ 1 1 1 1 1 1 −1 −1 1 −1 −1 1 1 −1 1 −1 ] (19) A divisão por oito na Equação 19 não é realizada no cálculo da Hadamard inversa, no entanto, é compensado durante a quantização inversa. O mesmo procedimento aplicado à Equação 18 resulta na equação para transformada inversa de Hadamard aplicada aos blocos 2x2 de crominâncias. XC =[1 1 1 −1]·YC ·[1 1 1 −1] (20) 3.4.3 Quantização O padrão H.264 conta com um módulo quantizador escalar. A quantização dos coeficientes obtidos pelas transformadas resulta na redução da informação e, consequentemente, na compressão dos dados. A quantização consiste, basicamente, de uma divisão por valor inteiro, de maneira a reduzir a faixa dos valores (RICHARDSON, 2003).
  • 46. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 46 A equação básica que define a quantização é: FQij=round  Xij Qstep  (21) Onde FQ é o resultado da quantização; X é o valor a ser quantizado; Qstep é o passo de quantização; round é uma função que aproxima o valor para o inteiro mais próximo. O parâmetro Qstep determina a intensidade da quantização, ou seja, quanto maior o Qstep maior a compressão atingida e, consequentemente, maior a perda de informação gerada no arredondamento. A determinação do valor do Qstep é um passo importante na configuração do codificador (MAJOLO, 2010). A determinação do Qstep é realizada indiretamente através de uma tabela com 52 valores que podem ser assumidos pelo Qstep, que são indexados pelo Quantization Parameter (QP). A relação entre o Qstep e QP é a seguinte: para cada incremento de seis unidades do QP, o Qstep é multiplicado por dois. Essa relação é apresentada na Tabela 3. A utilização desta tabela foi adotada a fim de evitar a necessidade de operações custosas como, cálculos com ponto flutuante e divisões (RICHARDSON, 2003). Tabela 3 Passos de quantização. QP 0 1 2 3 4 5 6 7 8 9 10 11 12 ... Qstep 0,625 0,6875 0,8125 0,875 1 1,125 1,25 1,37 5 1,62 5 1,75 2 2,25 2,5 QP ... 18 ... 24 ... 30 ... 36 ... 42 ... 48 ... 51 Qstep 5 10 20 40 80 160 224 Fonte: RICHARDSON, 2003 Como foi mencionado na subseção sobre a transformada DCT, uma multiplicação escalar oriunda daquela transformada não é implementada, precisando ser compensada durante a quantização. Essa compensação é feita através da variável Post-Scaling Factor (PF), definida pela Tabela 4, resultando na Equação 22. As variáveis a e b são definidas nas Equações 13 e 14. FQij=round X ij · PF Qstep  (22)
  • 47. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 47 Tabela 4 Valores de PF para cada posição. Posição (i, j) PF (0,0), (2,0), (0,2) e (2,2) a² (1,1), (1,3), (3,1) e (3,3) b²/4 Outras ab/2 Fonte: RICHARDSON, 2003. Para fins de substituir divisões por deslocamento de bits, o termo PF / Qstep na Equação 22 pode ser substituído por: PF Qstep = MF 2 qbits (23) Onde MF é o fator de multiplicação definido na Tabela 5; qbits é definido por qbits=15 floor  QP 6  (24) sendo floor a função que realiza o arredondamento para baixo. A equação final, em aritmética inteira, é expressa por: ∣FQij ∣=∣X ij ∣· MF f ≫qbits (25) signFQij =signX ij  (26) Onde f é 2qbits /3 para blocos da predição intra e 2qbits /6 para blocos da predição inter; >> é o descolocamento binário para direita; sign é a função que acessa o sinal do número. Tabela 5 Fator de multiplicação. Posições Posições QP (0,0), (2,0), (2,2) e (0,2) (1,1), (1,3), (3,1) e (3,3) Outras posições 0 13107 5243 8066 1 11916 4660 7490 2 10082 4194 6554 3 9362 3647 5825 4 8192 3355 5243 5 7282 2893 4559 Fonte: RICHARDSON, 2003. Por fim, apresenta-se a definição da quantização inversa, que serve para recuperar o valor anterior. Como a quantização é um procedimento que causa perdas, o valor recuperado é uma aproximação do valor original, que depende do parâmetro QP. Este parâmetro terá o
  • 48. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 48 mesmo valor na quantização direta e inversa. A equação da quantização inversa para os componentes AC7 de luminâncias é definida em 27. X 'ij=FQij ·Vij ·2 QP/6 (27) Onde X'ij é o valor recuperado; FQij é o valor quantizado; Vij é uma constante definida em 28; QP é o parâmetro de quantização. Vij=Qstep · PFij ·64 (28) A quantização inversa para os componentes DC é expressa pela equação 29. X 'ij=FQij ·V0,0 ·2  floor QP/6 para QP >= 12 X 'ij=[ FQij ·V0,0 ·2 1− floor QP/6 ]≫QP/6 para QP < 12 (29) Onde floor é operação que arredonda o número para baixo; >> é deslocamento binário para direita. 3.4.4 Estimativa de movimento A estimação de movimento trabalha no modelo temporal do vídeo com o objetivo de encontrar e remover dados redundantes em quadros temporalmente adjacentes, algo relativamente comuns em sequências de vídeo naturais. A partir do modelo temporal, aproveitam-se as similaridades entres os quadros baseando-se em dados previamente processados a fim de obter um quadro estimado (RICHARDSON, 2002). A Figura 13 apresenta dois quadros temporalmente consecutivos no vídeo. Já a Figura 14a ilustra a similaridade entre os dois quadros através da codificação diferencial, ou seja, o quadro é obtido através da simples subtração entre os dois quadros originais. Nas figuras, o tom acinzentado predominante indica as regiões em que não há diferença entre os dois quadros, o que pode ser explorado para reduzir a quantidade de dados realmente necessários para construir a segunda imagem a partir da primeira. A utilização das técnicas de estimação de movimento possibilitam reduzir os resíduos obtidos pela codificação diferencial. A Figura 14b ilustra o resíduo obtido após a realização da estimação de movimento. 7 Coeficientes AC são aqueles que possuem frequência diferente de zero.
  • 49. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 49 (a) (b) Figura 13 Quadros consecutivos de vídeo (RICHARDSON, 2003). (a) (b) Figura 14 Na esquerda, o resíduo sem estimativa de movimento. Na direita, o resíduo com estimativa de movimento (RICHARDSON, 2003). A obtenção da estimativa de movimento se dá pela determinação de qual bloco dos quadros de referência mais se assemelha ao macrobloco que está sendo processado, a fim de que possa-se codificar apenas a diferença entre o bloco atual e o bloco selecionado e um vetor de movimento que define a posição da região usada na predição. Este vetor é incluído no bitstream de forma a permitir ao decodificador a realização do processo inverso (compensação de movimento) (PORTO, 2008). A estimação de movimento baseia-se em algoritmos de busca, que visam encontrar o bloco que possui a maior similaridade com o bloco atual (melhor casamento), e em critérios de similaridade que serão detalhados nas subseções seguintes. A Figura 15 ilustra o procedimento de estimativa de movimento, que em conjunto com a compensação de movimento constitui a predição interquadro. Segundo (PURI; CHEN; LUTHRA, 2004) o codificador interquadros é o módulo que contém a maior complexidade computacional em um codificador de vídeo. O padrão H.264/AVC inovou na predição interquadro ao inserir a possibilidade de blocos de tamanho variável, interpolação de valores intermediários (atingindo resolução de
  • 50. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 50 meio ou quarto de pixel) e utilização de múltiplos quadros de referência (incluindo quadros futuros) (RICHARDSON, 2003). Figura 15 Predição interquadro (DINIZ, 2009). 3.4.4.1 Algoritmos de busca Os algoritmos de busca especificam como a busca pelo bloco com maior similaridade será realizada dentro de uma área de tamanho pré-definido chamada janela de busca. Em geral, os algoritmos mais utilizados são os baseados em blocos de pixeis (em oposição aos baseados em objetos). A escolha de um algoritmo de busca é extremamente importante, pois tem impacto significativo, tanto na eficiência da compressão, quanto na complexidade computacional do codificador (PORTO, 2012). Os algoritmos de busca podem ser divididos em algoritmos ótimos e rápidos: os algoritmos ótimos obtém o vetor de movimento correspondente ao bloco com maior similaridade em relação ao bloco atual através da análise de todos os possíveis candidatos. Por outro lado, os algoritmos rápidos obtém uma diminuição do tempo de busca através de heurísticas que diminuem a quantidade de candidatos a serem analisados, ao custo de obterem um vetor de movimento subótimo (PORTO, 2008). O algoritmo Full Search (FS) é um algoritmo ótimo, pois compara a similaridade de todos os possíveis blocos dentro da janela de busca. A iteração sobre todos os candidatos pode ser de diversas formas, começando no canto superior esquerdo e finalizando no canto inferior direito ou realizando uma busca em formato de espiral ao redor de uma posição central, por
  • 51. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 51 exemplo. Os diferentes blocos candidatos são obtidos através do deslocamento da borda do bloco em uma amostra, conforme ilustrado na Figura 16. Figura 16 Algoritmo de busca completa (PORTO, 2012) O algoritmo FS dificilmente é empregado em aplicações práticas que requerem codificação em tempo real de altas resoluções, a menos que seja utilizada uma arquitetura desenvolvida especialmente para este fim. Este algoritmo não possui dependência de dados, portanto, é possível explorar um grande nível de paralelismo (SOARES, 2007). Os algoritmos rápidos tentam obter bons vetores de movimentos mesmo sem fazer uma busca exaustiva, ou seja, sem testar todos os possíveis blocos. Dentre as diversas formas de realizar a busca propostas na literatura, a seguir serão abordados dois algoritmos de interesse no contexto deste trabalho: Diamond Search (DS) e Logarithmic Search (LS). O algoritmo DS é um algoritmo rápido que realiza a busca em um formato de diamante. Este formato determina a posição dos blocos considerados candidatos dentro da janela de busca. Usualmente, esse algoritmo emprega dois padrões de busca: Large Diamond Search (LDS) e Small Diamond Search (SDS) (ZHU; MA, 2000). Inicialmente a LDS compara as similaridades entre o bloco atual e nove blocos candidatos ao redor da posição central da janela de busca. Se o bloco que resultar no menor resíduo não estiver no centro do diamante, esta etapa será repetida com base em uma nova posição central localizada no melhor bloco encontrado. Este procedimento se repete até que o bloco de maior similaridade esteja na posição central. Num segundo momento, a SDS realiza um refinamento ao redor da posição determinada na etapa anterior. Para tanto, é realizada a comparação entre a similaridade da posição central e de quatro blocos vizinhos. A Figura 17
  • 52. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 52 ilustra este procedimento. As posições “L” fazem parte do diamante grande e “S” do diamante pequeno. Figura 17 Large Diamond Search (LDS) e Small Diamond Search (SDS) (PORTO, 2008) O algoritmo LS, inicialmente, compara o bloco atual com cinco blocos candidatos: a posição (0, 0) e quatro blocos a S pixeis da origem na horizontal e na vertical, onde S é o valor do passo inicial. Na etapa seguinte, a origem é posicionada no melhor bloco encontrado na etapa anterior e o procedimento é repetido nessa nova posição. Quando o melhor casamento ocorrer na posição central o valor do passo é dividido por dois, até que o passo chegue ao valor um. Na sequência, as oito posições ao redor do bloco anteriormente selecionado são testadas. O bloco com menor similaridade nesta etapa resulta no vetor de movimento para a realização da predição. A Figura 18 ilustra o funcionamento do algoritmo LS com o passo S valendo dois inicialmente. No exemplo dado, para cada iteração da busca o bloco com maior similaridade é destacado em negrito. Figura 18 Algoritmo de busca logarítmica (RICHARDSON, 2002). A quantidade de iterações executadas na LDS depende do vídeo em questão, o que dificulta a análise do desempenho. Entretanto, o algoritmo DS diminui, em média, cerca de 150 vezes o número de blocos candidatos a terem a similaridade calculada e comparada, em relação ao algoritmo de busca completa (PORTO, 2012). No padrão de busca LS ocorre a
  • 53. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 53 mesma situação: o número de comparações necessárias depende da quantidade de iterações efetuadas e varia em cada caso. Uma técnica muitas vezes empregada conjuntamente a algoritmos de busca rápidos como DS e LS é a determinação de uma posição inicial para a busca diferente de (0, 0) através de vetores de movimento previamente obtidos (TOURAPIS, 2001). Por exemplo, pode-se determinar a posição inicial da busca baseando-se nos vetores de movimento encontrados nos blocos adjacentes do quadro atual. Essa ideia explora a localidade espacial, ou seja, o fato de que blocos vizinhos tendem a ter movimentação semelhante. No entanto, dessa forma cria-se uma dependência de dados entre os blocos de um mesmo quadro, o que dificulta a utilização de paralelismo em nível de bloco. Uma outra alternativa é escolher a posição inicial de busca a partir de dados proveniente de quadros previamente processados, ou seja, a exploração da localidade temporal. Essa ideia baseia-se na premissa de que o mesmo bloco em quadros temporalmente adjacentes possuam movimentação semelhante. Essa abordagem cria uma dependência de dados entre os quadros, mas, possibilita o paralelismos em nível de blocos dentro de um mesmo quadro. 3.4.4.2 Critérios de similaridade Os critérios de similaridade são usados para determinar o grau de semelhança entre dois blocos de pixeis. Diversos critérios foram propostos na literatura: Mean Square Error (MSE), Mean Absolute Error (MAE), Sum of Absolute Differences (SAD) entre outros (RICHARDSON, 2002). A Equação 30 define o cálculo do SAD, que é usualmente empregado na estimativa de movimento devido a sua simplicidade e em resultar em uma boa aproximação da energia do bloco (PORTO, 2012). SAD=∑ i =0 N −1 ∑ j=0 N −1 ∣Cij−Rij ∣ (30) Onde N é o tamanho do bloco Cij é o pixel na posição (i,j) do bloco atual Rij é o pixel na posição (i,j) do bloco de referência
  • 54. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 54 3.4.5 Compensação de movimento A compensação de movimento tem por objetivo encontrar, a partir do vetor de movimento obtido pela estimação de movimento, os blocos mais semelhantes com o atual dentre os blocos previamente codificados para obter o bloco predito. Para tanto, a compensação de movimento necessita obter os parâmetros gerados pela estimação de movimento (AZEVEDO, 2006). O vídeo será, inicialmente, reconstruído com base no quadro predito. Em seguida, serão corrigidas as diferenças entre o quadro original e o quadro estimado, utilizando o quadro residual. 3.5 Trabalhos relacionados Sprandlin et al. (2009) avaliaram a viabilidade de paralelizar a implementação de referência do codificador MPEG-2, utilizando a tecnologia CUDA, e obtiveram significativos ganhos de velocidade em partes específicas da implementação. No entanto, esses resultados são severamente diluídos se analisado o aplicativo como um todo. Foi destacada a importância de minimizar as transferências de dados entre a CPU e a placa de vídeo, pois a alta latência e a pequena largura de banda do barramento PCIe foram apontadas como fatores que limitaram os resultados. Chan et al. (2009) demonstraram a viabilidade de implementar o algoritmo piramidal de estimação de movimento do padrão H.264 utilizando CUDA. O resultado obtido foi uma diminuição de 56 vezes no tempo gasto na execução do algoritmo, no entanto, foi utilizada uma aproximação do vetor predito a fim de eliminar interdependências que diminuiriam o nível de paralelismo alcançável. Ren et al. (2010) propuseram duas implementações do módulo de predição-intra do codificador H.264 em GPU. Na primeira implementação, foram eliminados dois modos de predição a fim de alcançar um maior paralelismo em nível de blocos 4x4. A outra alternativa explora o paralelismo em nível de macrobloco. No entanto, para eliminar as dependências entre macroblocos vizinhos é necessária uma alteração no algoritmo (com consequências insignificantes na qualidade em vídeos de alta definição). Os ganhos obtidos nas duas implementações propostas ficaram em torno de cinco vezes em relação à implementação de referência. Huang, Shen e Wu (2009) estudaram a utilização de CPUs multi núcleo em conjunto com GPUs, atuando como coprocessadores, para a implementação de um codificador de vídeo
  • 55. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 55 H.264/SVC (extensão do H.264/AVC com técnicas de codificação escalável). Foi estudada a divisão das tarefas entre as duas arquiteturas (CPUs e GPUs) e a transição de dados entre elas. Os resultados obtidos apontaram que a execução do algoritmo de busca completa na estimativa de movimento na GPU resultou em melhor desempenho se comparado à implementação utilizando CPU multi núcleo. Cheung et al. (2010) investigaram o uso de GPUs para codificação e decodificação de vídeo. Este trabalho faz uma revisão da literatura acerca da estruturação e particionamento dos módulos entre CPU e GPU. Por fim, é implementada a estimativa de movimento do H.264 na GPU, através da qual é explorado o trade-off entre os ganhos de velocidade e a qualidade obtida. Os experimentos levam a resultados de execução cerca de três vezes mais rápida com a utilização da GPU e foi destacada a importância de expor o máximo paralelismo de dados possível à GPU. Monteiro et al. (2011) exploraram o uso da arquitetura CUDA no contexto da estimativa de movimento, obtendo um ganho de velocidade de 600 vezes na implementação do algoritmo de busca completa.
  • 56. BDU–BibliotecaDigitaldaUNIVATES(http://www.univates.br/bdu) 56 4 DESCRIÇÃO DO SISTEMA DESENVOLVIDO O aumento na complexidade computacional no padrão H.264 em relação aos padrões anteriores é significante. Essa característica torna desafiadora a implementação de um sistema capaz de executar a codificação em tempo real, especialmente para vídeos de alta resolução (DINIZ, 2009). Inserido nesse contexto, o presente trabalho consiste na investigação da utilização de GPUs, presentes nas placas de vídeo da NVIDIA, como coprocessadores no contexto da codificação de vídeo. Para tanto, utilizou-se a tecnologia NVIDIA CUDA, apresentada no segundo capítulo deste trabalho. Um ponto importante foi a identificação dos algoritmos de codificação de vídeo que são apropriados à implementação em arquiteturas paralelas. Por isso, faz-se necessária a revisão de literatura apresentada previamente e o estudo da implementação de referência do codificador H.264. A complexidade computacional dos diversos módulos do codificador H.264 foi analisada em diversos trabalhos encontrados na literatura. Em geral, as análises consideram o tempo de processamento necessário por cada módulo, o que equivale aproximadamente ao número de operações executadas (HOROWITZ, 2003). A Tabela 6 apresenta o percentual da complexidade computacional dos principais módulos do H.264, segundo a avaliação de Zhang et al. (2005). Tabela 6 Complexidade dos módulos do codificador H.264. Módulo Complexidade % ME / MC 81,78 T / Q / T-1 / Q-1 5,49 Predição intraquadro 5,29 Filtro 0,82 Outros 6,62 Fonte: ZHANG et al., 2003. Pode-se notar claramente que a parcela mais significativa localiza-se na estimativa e compensação de movimento. Essas técnicas situam-se na predição interquadro, ou seja, exploram as redundâncias temporais do vídeo. Por outro lado, na exploração das redundâncias espaciais dentro de um quadro do vídeo, destacam-se as transformadas e quantização diretas e inversas (que juntas compõe o que pode ser chamado de módulo computacional) e a própria predição intraquadro. O desenvolvimento deste trabalho foi dividido em duas etapas: o estudo dos algoritmos relacionados à codificação intraquadro e codificação interquadro.