Eu tenho um filtro simples de passa-baixo simples (para suavização de parâmetros) que pode ser explicado pela seguinte fórmula:
A arquitetura que estou usando tem acesso a instruções de instrução única e dados múltiplos (SIMD) que podem executar vários cálculos vetorizados em paralelo. Gostaria de aproveitar esse recurso, mas não tenho certeza de como fazer isso para um filtro recursivo como esse. O problema é que todo cálculo precisa de um resultado anterior.
filters
infinite-impulse-response
user1132968
fonte
fonte
Respostas:
Supondo que você execute operações vetoriais elementos de cada vez, é possível desenrolar a equação da diferença por um fator bastante facilidade para o filtro simples de um pólo. Suponha que você já calculou todas as saídas até . Em seguida, você pode calcular os seguintes: M y [ n ] y [ n + 1 ]M M y[n]
Em geral, você pode escrever como:y[n+k]
Para cada índice de amostra , isso se parece com um filtro FIR com toques: um toque multiplica a última saída de filtro e os outros toques multiplicam as entradas de filtro . O bom é que os coeficientes utilizados para todas estas torneiras pode ser pré-calculada, o que lhe permite desenrolar o filtro recursivo em -Toque paralelo filtros não recursivos (estes filtros calcular as amostras de saída ), atualizando o termo de feedback a cada amostras de saída. Então, dada uma condição inicialn+k k+1 y[n] k x[n+1],…,x[n+k] M M+1 y[n+1],…,y[n+M] M y[n] (que é considerado a última saída calculada na iteração vetorial anterior), é possível calcular as próximas saídas em paralelo.M
Existem algumas ressalvas nessa abordagem:
Se se tornar grande, você acaba multiplicando vários números para obter os coeficientes FIR efetivos para os filtros desenrolados. Dependendo do seu formato numérico e do valor de , isso pode ter implicações numéricas de precisão.M a
Além disso, você não obtém uma aceleração fold com essa abordagem: acaba calculando com o que equivale a um filtro FIR tap. Embora você esteja calculando saídas em paralelo, o fato de você ter que executar operações multiply-acumulate (MAC) em vez da implementação recursiva simples de primeira ordem diminui alguns dos benefícios da vetorização. A abordagem não vetorizada usa 2 MACs por saída, portanto, você precisa de operações de para calcular saídas. O esquema vetorizado calcula as saídas uma só vez, exigindo MACs no processo. Portanto, a redução nas operações pode ser expressa em função daM y[n+k] k M k 2M M M M+1 M
fonte
Em geral, você só pode vetorizar conjuntos de cálculos completamente independentes. Mas no seu passe baixo IIR, toda saída depende de outra (exceto a 1ª), portanto, a vetorização não é possível.
Se sua variável "a" for grande o suficiente para que (1-a) ^ n decaia rapidamente abaixo do nível de ruído desejado ou erro permitido, você poderá substituir uma aproximação curta do filtro FIR pelo seu IIR e, em vez disso, vetorizar essa convolução. Mas não é provável que seja mais rápido.
fonte
Você realmente pode vetorizar isso efetivamente se tiver mais de um sinal ao qual deseja aplicar o mesmo filtro, por exemplo, se for um sinal de áudio estéreo, poderá processar os canais esquerdo e direito em paralelo. Quatro ou oito canais em paralelo obviamente seriam ainda melhores.
fonte
Que tal expandir equações para 4 etapas e usar a multiplicação de matrizes? a é constante, então uma matriz pode ser pré-calculada
fonte
É mais eficiente vetorizar a filtragem de vários fluxos independentes em paralelo.
Se você tiver apenas um único fluxo longo, poderá dividi-lo em várias seções sobrepostas e filtrá-las como se fossem fluxos independentes.
Você deseja uma sobreposição porque as primeiras amostras de cada fluxo estarão incorretas. A quantidade de amostras que você precisa descartar dependerá do valor de a e da precisão desejada. Você desejará descartar cerca de n amostras em que (1 / a) (1-a) ** n <eps para que o resultado seja preciso para eps * max (| x [i] |).
Por exemplo, se a = 0,1, em 128 amostras o erro causado por (1 / a) (1-a) ^ n seria menor que o LSB em um número inteiro de 16 bits, enquanto que para a = 0,9 você precisaria apenas descartar cerca de 6 amostras.
fonte