• Nenhum resultado encontrado

4.2 Processamento de ´ audio em tempo real usando CUDA e GPUs da Nvidia

4.2.3 Especificidades da GPU

Como comentado na Se¸c˜ao 4.1, o balan¸co entre fun¸c˜oes fixas e unidades program´aveis ´e funda- mental para o aumento da generalidade e desempenho das GPUs. Ao longo do desenvolvimento dos dispositivos gr´aficos, algumas fun¸c˜oes fixas foram cristalizadas por terem importˆancia fundamental para auxiliar a computa¸c˜ao ao longo dos est´agios da pipeline da GPU. ´E o caso, por exemplo, das fun¸c˜oes trigonom´etricas e da mem´oria de texturas (e suas opera¸c˜oes associadas, como leitura interpolada de ´ındices fracion´arios). A natureza destas fun¸c˜oes coincide com algumas opera¸c˜oes b´asicas utilizadas nos algoritmos de processamento de ´audio, e assim sua utiliza¸c˜ao pode aumentar o desempenho da GPU no processamento de ´audio em tempo real.

Na implementa¸c˜ao do Phase Vocoder para GPU, mais especificamente no est´agio de ress´ıntese implementado utilizando s´ıntese aditiva, o uso da leitura interpolada de ´ındices fracion´arios da mem´oria de texturas e da fun¸c˜ao trigonom´etrica sin(), embutidas no hardware da GPU, oferece possibilidade imediata de compara¸c˜ao com a t´ecnica de c´alculo de uma fun¸c˜ao senoidal baseada em interpola¸c˜ao (linear ou c´ubica, no caso desta explora¸c˜ao), atrav´es da leitura de ´ındices fracion´arios de uma tabela contendo os valores de um per´ıodo da fun¸c˜ao seno.

4.2.4 Implementa¸c˜ao

Para implementar a utiliza¸c˜ao do Pd com GPU, o primeiro passo foi desenvolver um modelo de external que inicializa a placa GPU e controla a transferˆencia de mem´oria e chamadas de fun¸c˜oes de kernel de acordo com os ciclos DSP do Pd. Em seguida, este modelo foi copiado para implementar os diferentes algoritmos testados (FFT e Phase Vocoder), e um conjunto de shell-scripts foi escrito para auxiliar a execu¸c˜ao automatizada dos testes. Esta se¸c˜ao descreve alguns detalhes importantes da estrutura de testes desenvolvida.

Estrutura (orientada a objetos) de um external

Um diagrama desenhado no Pd ´e chamado patch. Os objetos gr´aficos que podem ser utilizados para compor um diagrama de processamento em um patch podem ser de um de trˆes tipos: abs- tractions, built-ins ou externals. Abstra¸c˜oes s˜ao outros patches criados com o Pd e encapsulados em um objeto, e podem possuir entradas e sa´ıdas de fluxos de ´audio e controle atrav´es, respec- tivamente, dos pares de objetos (inlet∼, outlet∼) e (inlet, outlet). Built-ins s˜ao objetos bin´arios escritos em C e compilados junto com o arquivo bin´ario principal do Pd. Por sua vez, os externals tamb´em s˜ao objetos escritos em C, mas compilados como bibliotecas dinˆamicas que podem ser carregadas em tempo de execu¸c˜ao.

Os externals devem aderir ao modelo de orienta¸c˜ao a objetos utilizado em todo o c´odigo do Pd, e devem possuir um conjunto minimal de fun¸c˜oes para viabilizar a cria¸c˜ao e opera¸c˜ao de objetos gr´aficos na constru¸c˜ao de um patch. As seguintes componentes s˜ao o m´ınimo necess´ario para codificar um external que processa ´audio:

• Estrutura de dados: Uma estrutura de dados que representa o objeto do external. Uma por¸c˜ao de mem´oria contendo uma instˆancia desta estrutura ´e disponibilizada para o m´etodo de processamento de ´audio (veja abaixo) junto com os sinais processados. Ela deve conter campos para armazenar os parˆametros de controle que o objeto pode receber, ponteiros para regi˜oes de mem´oria alocadas dinamicamente e outros valores dos quais o objeto necessite para sua opera¸c˜ao.

4.3 RESULTADOS E DISCUSS ˜AO 65 • M´etodo de cria¸c˜ao de um novo objeto: Este m´etodo deve criar uma estrutura de dados do tipo descrito no item anterior, inicializar seus valores e retornar o valor do ponteiro para a estrutura criada.

• M´etodo de processamento de ´audio: Este ´e o m´etodo de manipula¸c˜ao dos sinais de ´

audio. Ele recebe as configura¸c˜oes atuais do Pd e um ponteiro para a estrutura de dados que representa a instˆancia atual do objeto do Pd e pode trabalhar em cima dos buffers com as amostras de ´audio para produzir o efeito desejado.

• M´etodo de inicializa¸c˜ao do processamento: Executado sempre que o processamento de ´audio ´e iniciado, este m´etodo inclui o m´etodo acima em uma fila de m´etodos que ser˜ao executados para processar os sinais ao longo do diagrama.

• M´etodo de configura¸c˜ao de classe: A quantidade e tipos de entradas e sa´ıdas do objeto, o m´etodo de cria¸c˜ao de um novo objeto e o m´etodo de inicializa¸c˜ao do processamento s˜ao configurados por este m´etodo.

Inicializa¸c˜ao da placa GPU

A inicializa¸c˜ao da placa GPU consiste na configura¸c˜ao do n´umero da placa a ser utilizada (pode haver diversas placas num mesmo hospedeiro) e aloca¸c˜ao e inicializa¸c˜ao de mem´oria para computa¸c˜ao no dispositivo. Estas tarefas podem ser realizadas no m´etodo de cria¸c˜ao de um novo objeto, tomando os devidos cuidados para evitar que duas instˆancias de um mesmo external n˜ao interfiram na computa¸c˜ao um do outro.

Organiza¸c˜ao do c´odigo e compila¸c˜ao

Para melhor organiza¸c˜ao do c´odigo ´e interessante encapsular toda a parte que lida com a GPU (fun¸c˜oes de kernel e fun¸c˜oes que fa¸cam chamadas a fun¸c˜oes de kernel de forma que sejam especificadas em arquivos com extens˜ao .cu e que possam ser compiladas pelo compilador do CUDA. Assim, a parte do c´odigo que lida somente com fun¸c˜oes escritas em C pode continuar sendo compilada pelo compilador convencional, enquanto que todas as partes que lidam com c´odigo escrito em CUDA-C podem ser compiladas pelo nvcc, compilador espec´ıfico distribu´ıdo junto com o arcabou¸co CUDA.

Fun¸c˜oes que lidam com a GPU

As chamadas de fun¸c˜oes que lidam com a GPU s˜ao, em geral, de trˆes tipos: aloca¸c˜ao ou libera¸c˜ao de mem´oria, fun¸c˜oes de kernel dispon´ıveis na biblioteca CUDA, ou fun¸c˜oes de kernel especificadas pelo usu´ario. Na implementa¸c˜ao desenvolvida, a aloca¸c˜ao de mem´oria na GPU ´e realizada na cria¸c˜ao do objeto, e a transferˆencia de dados e as chamadas `as fun¸c˜oes de kernel s˜ao feitas a cada ciclo DSP no m´etodo de processamento.

4.3

Resultados e discuss˜ao

Foram utilizados dois ambientes de testes, com um total de trˆes modelos distintos de pla- cas Nvidia GPU. O primeiro ambiente ´e um computador Intel(R) Core(TM) i7 CPU 920 @2.67GHzcom 8 cores e 6 GB RAM, rodando Ubuntu GNU/Linux 11.10 com vers˜ao de ker- nel 3.0.0-32-generic, e equipado com dois modelos de placa Nvidia GPU: Geforce GTX 275 e Geforce GTX 470. O segundo ambiente de testes ´e um computador Intel(R) Core(TM) i7-3930K CPU @ 3.20GHz, com 12 cores e 24 GB RAM, rodando Ubuntu GNU/Linux 12.10 com vers˜ao de kernel 3.5.0-24-generic, equipado com uma placa Nvidia Quadro GF 100 GL. Foram utilizadas a vers˜ao 5.0 da plataforma CUDA e a vers˜ao 0.44-0 do Pure Data para rodar os externals desenvolvidos.

66 PROCESSAMENTO DE ´AUDIO EM TEMPO REAL EM GPU 4.3 0 0.5 1 1.5 2 2.5 3 ... 214 215 216 217 Duracao (s) Tamanho do bloco Tempo de roundtrip da FFT - GTX275 0 0.5 1 1.5 2 2.5 3 ... 214 215 216 217 Duracao (s) Tamanho do bloco Tempo de roundtrip da FFT - GTX470 0 0.5 1 1.5 2 2.5 3 ... 214 215 216 217 Duracao (s) Tamanho do bloco Tempo de roundtrip da FFT - GF100GL hospedeiro para dispositivo

tempo de kernel dispositivo para hospedeiro roundtrip rt period

Figura 4.5: Tempo de transferˆencia de mem´oria e de execu¸c˜ao da FFT para diferentes tamanhos de bloco em diferentes modelos de placa de v´ıdeo GPU.

Um resumo das caracter´ısticas de cada placa pode ser visto na pr´oxima tabela:

Modelo Cores Mem (MB) Mem BW (GB/s)

GTX 275 240 896 127.0

GTX 470 448 1280 133.9

GF 100 256 2000 89.6

Para avaliar o desempenho do esquema utilizado para DSP em tempo real usando a GPU, o primeiro passo foi implementar um external de FFT utilizando a biblioteca CUFFT, que transfere dados para a GPU, executa o algoritmo sobre destes dados, e finalmente transfere os dados de volta para a mem´oria do computador. Os resultados para diferentes tamanhos de bloco podem ser vistos nas Figuras 4.5 e 4.6, e ser˜ao discutidos na pr´oxima se¸c˜ao. Bastante tempo de computa¸c˜ao ainda fica dispon´ıvel ap´os o c´alculo da FFT, mesmo considerando o tempo de transferˆencia de mem´oria. Para verificar a possibilidade de uso da GPU em tarefas mais intensas, tamb´em foram implementados os algoritmos de convolu¸c˜ao e Phase Vocoder.

A implementa¸c˜ao da convolu¸c˜ao ´e imediata: toma-se dois sinais de entrada conectados a um objeto do Pd e realiza-se a convolu¸c˜ao dos dois sinais calculando cada amostra da sa´ıda em paralelo, como descrito na Se¸c˜ao 4.2.2. Como a entrada do algoritmo s˜ao dois sinais de ´audio, a quantidade de mem´oria transferida aqui ´e o dobro da quantidade transferida no caso anterior do c´alculo da FFT de apenas um sinal. O resultado do tempo total de execu¸c˜ao, somando o tempo de transferˆencia de mem´oria e o tempo de execu¸c˜ao da fun¸c˜ao de kernel que realiza a convolu¸c˜ao pode ser visto na Figura 4.7.

4.3 RESULTADOS E DISCUSS ˜AO 67 0 0.05 0.1 0.15 0.2 ... 214 215 Duracao (s) Tamanho do bloco

Tempo de roundtrip da FFT (zoom) - GTX275

0 0.05 0.1 0.15 0.2 ... 214 215 Duracao (s) Tamanho do bloco

Tempo de roundtrip da FFT (zoom) - GTX470

0 0.05 0.1 0.15 0.2 ... 214 215 Duracao (s) Tamanho do bloco

Tempo de roundtrip da FFT (zoom) - GF100GL hospedeiro para dispositivo

tempo de kernel dispositivo para hospedeiro roundtrip dsp period

Figura 4.6: Por¸c˜ao inicial do gr´afico anterior do tempo de transferˆencia de mem´oria e de execu¸c˜ao da FFT para diferentes tamanhos de bloco em diferentes modelos de placa de v´ıdeo GPU.

2 4 6 8 10 ... 214 215 216 217 Duracao (s) Tamanho do bloco

Tempo de convolucao - todas as placas

0.2 0.4 0.6 0.8 ... 212 213 214 215 Duracao (s) Tamanho do bloco

Tempo de convolucao (zoom) - todas as placas GTX275

GTX470 GF100GL rt period

68 PROCESSAMENTO DE ´AUDIO EM TEMPO REAL EM GPU 4.3

Uma implementa¸c˜ao do Phase Vocoder para a GPU pode utilizar paralelismo de duas formas. Primeiro, pode estimar as amplitudes e frequˆencias instantˆaneas para cada oscilador fazendo uso da FFT paralela. Em seguida, como o resultado de cada amostra sintetizada n˜ao depende do c´alculo do valor de outras amostras de sa´ıda, o Phase Vocoder pode realizar uma s´ıntese aditiva em paralelo para cada amostra de sa´ıda de um bloco DSP. Assim, uma implementa¸c˜ao do Phase Vocoder na GPU transfere a mesma quantidade de dados entre o computador hospedeiro e o dispositivo que o algoritmo da FFT paralela, mas ´e composta de mais chamadas a fun¸c˜oes paralelas e mais computa¸c˜ao dentro de cada fun¸c˜ao.

A parte do c´odigo do Phase Vocoder que implementa a s´ıntese aditiva ´e computacionalmente intensa e bastante sens´ıvel em rela¸c˜ao ao m´etodo utilizado para obter o valor de cada oscilador senoidal, como observado por Savioja et al. (Savioja et al., 2011). Nos testes realizados, foram comparadas 5 implementa¸c˜oes distintas:

1. Consulta a tabela com interpola¸c˜ao c´ubica utilizando 4 pontos. 2. Consulta a tabela com interpola¸c˜ao linear utilizando 2 pontos.

3. Consulta a tabela com ´ındice truncado (sem interpola¸c˜ao). Note que a qualidade num´erica de uma consulta truncada pode ser melhorada aumentando-se o tamanho da tabela (e a GPU, diferentemente do que foi visto com o Arduino no cap´ıtulo anterior, possui mem´oria suficiente para tabelas grandes).

4. Primitiva trigonom´etrica da GPU. A fun¸c˜ao sinf() da API do CUDA computa um n´umero de ponto flutuante com precis˜ao dupla.

5. Primitiva de consulta a ´ındices fracion´arios na mem´oria de textura. A GPU se encarrega de realizar e retornar um valor interpolado linearmente.

Os resultados para tempos de transferˆencia de mem´oria e tempo de kernel da s´ıntese aditiva dos testes com o Phase Vocoder paralelo podem ser vistos nas Figuras 4.8 e 4.9, e tamb´em ser˜ao discutidos na pr´oxima se¸c˜ao.

Cada algoritmo (FFT, convolu¸c˜ao e Phase Vocoder) foi executado por um per´ıodo igual a 100 blocos DSP para tamanhos de bloco iguais a 2i, para 6 ≤ i ≤ 17, e em seguida foram calculados os tempos m´edios para a transferˆencia de dados (de ida e volta) e para a execu¸c˜ao das fun¸c˜oes de kernel relativas a cada algoritmo.

O maior tamanho de bloco considerado, de 217= 131.072 amostras, corresponde a um per´ıodo de por volta de 3 segundos de ´audio. Esta escolha de per´ıodo de um ciclo DSP pode parecer exagerada para utiliza¸c˜ao em tempo real, mas a latˆencia correspondente pode ser compensada pela escolha de um fator de sobreposi¸c˜ao grande de forma a manter o tamanho do bloco (e portanto a resolu¸c˜ao espectral associada) e obter maior resolu¸c˜ao temporal. O tempo de execu¸c˜ao do Phase Vocoder para blocos de amostras de tamanho maior do que 217 excede, para todas as implementa¸c˜oes, o per´ıodo do bloco DSP correspondente, de forma que este tamanho de bloco ´e suficiente para prover limitantes superiores para a viabilidade da computa¸c˜ao como fun¸c˜ao do tamanho do bloco em todos os modelos de GPU testados.

Comparando as figuras que descrevem apenas a FFT com as que descrevem a implementa¸c˜ao completa do Phase Vocoder, ´e poss´ıvel ver que h´a uma diferen¸ca not´avel, de algumas ordens de magnitude, entre o tempo utilizado para rodar cada um destes algoritmos. Comparando o tempo tomado pelos dois algoritmos para um mesmo modelo de placa, ´e poss´ıvel ver que a FFT toma tempo compar´avel ao tempo de transferˆencia de mem´oria, da ordem de d´ecimos de milissegundos, enquanto que a implementa¸c˜ao completa do Phase Vocoder toma v´arios segundos para tamanhos de bloco grandes. Isto indica que centenas de FFTs poderiam ser executadas em um ciclo DSP, enquanto que apenas alguns ciclos de an´alise e s´ıntese de Phase Vocoder poderiam ser executados na mesma quantidade de tempo.

4.3 RESULTADOS E DISCUSS ˜AO 69 5 10 15 20 25 30 ... 214 215 216 217 Duracao (s) Tamanho do bloco Tempo de sintese do PV - GTX275 5 10 15 20 25 30 ... 214 215 216 217 Duracao (s) Tamanho do bloco Tempo de sintese do PV - GTX470 5 10 15 20 25 30 ... 214 215 216 217 Duracao (s) Tamanho do bloco Tempo de sintese do PV - GF100GL 1. interpolacao cubica 2. interpolacao linear 3. consulta truncada 4. funcao seno 5. interpolacao de textura sem calculo rt period

Figura 4.8: Tempo de transferˆencia de mem´oria e de execu¸c˜ao da s´ıntese aditiva do Phase Vocoder para diferentes tamanhos de bloco em diferentes modelos de placa de v´ıdeo GPU.

0.2 0.4 0.6 0.8 1 ... 212 213 214 215 Duracao (s) Tamanho do bloco

Tempo de sintese do PV (zoom) - GTX275

0.2 0.4 0.6 0.8 1 ... 212 213 214 215 Duracao (s) Tamanho do bloco

Tempo de sintese do PV (zoom) - GTX470

0.2 0.4 0.6 0.8 1 ... 212 213 214 215 Duracao (s) Tamanho do bloco

Tempo de sintese do PV (zoom) - GF100GL 1. interpolacao cubica 2. interp linear 3. consulta truncada 4. funcao seno 5. interpolacao de textura sem calculo rt period

Figura 4.9: Por¸c˜ao inicial do gr´afico anterior do tempo de transferˆencia de mem´oria e de execu¸c˜ao da s´ıntese aditiva do Phase Vocoder para diferentes tamanhos de bloco em diferentes modelos de placa de v´ıdeo GPU.

70 PROCESSAMENTO DE ´AUDIO EM TEMPO REAL EM GPU 4.3 0 0.1 0.2 0.3 0.4 0.5 ... 214 215 216 217 Duracao (ms) Tamanho do bloco Memory transfer times - GTX275

0 0.1 0.2 0.3 0.4 0.5 ... 214 215 216 217 Duracao (ms) Tamanho do bloco Memory transfer times - GTX470

0 0.1 0.2 0.3 0.4 0.5 ... 214 215 216 217 Duracao (ms) Tamanho do bloco Memory transfer times - GF100GL

FFT: hosp. p/ disp. FFT: disp. p/ hosp. convolution: hosp. p/ disp. convolution: disp. p/ hosp. PV: hosp. p/ disp. PV: disp. p/ hosp.

Figura 4.10: Tempo de transferˆencia de mem´oria para os algoritmos FFT, convolu¸c˜ao e PV, para cada uma das placas.