Exponencial Moving Average C ++
Tenho perfilado isso usando o Profiler Visual C, e ele representa cerca de 35 do tempo de execução Esta média móvel exponencial é chamado mais de um trilhão de vezes, porque ele é usado repetidamente no processamento de mais de 400 gigabytes de dados Os dados está saindo Um Raid Nível 0 matriz de disco de estado sólido, de modo a ler as contas de dados para menos de 5 do tempo O tamanho do preço é de cerca de 100 Eu originalmente acelerado por um fator de 4 por precalculating tanto dos dados quanto possível Então eu estava Capaz de aumentá-lo novamente por um fator de PaeneInsula Oct 30 11 em 20 41.I foi capaz de aumentar a velocidade novamente por um fator de 12 multithreading-lo a natureza dos dados é tal que pode ser multithreaded de tal forma que o Carga é perfeitamente equilibrado E eu tenho que correr em um i7 990x que tem 6 núcleos, hyperthreaded de um total de 12, overclocked PaeneInsula Oct 30 11 at 20 51.Sure, multithreading pode ajudar Mas você pode quase certamente melhorar o desempenho em um único Rosqueada. Primeiro, você está calculando-o na direção errada Somente as máquinas mais modernas podem fazer prefetching de passo negativo Quase todos os machihnes são mais rápidos para strides de unidade Eu e mudando a direção da matriz para que você digitalizar de baixo para alto em vez de alto para baixo é Quase sempre better. Next, reescrevendo um pouco - por favor, permita-me encurtar os nomes das variáveis para torná-lo mais fácil de type. By a maneira, vou começar a usar o st para o preço e s para suavização, para salvar a digitação I m lazy. but É provavelmente mais rápido para fazer. A latência entre avg i e avg i-2 é então 1 multiplicação e uma adição, ao invés de uma subtração e uma multiplicação entre avg i e avg i-1 I e mais do dobro de fast. In geral , Você quer reescrever a recorrência de modo que avg i é calculado em termos de avg j para j tão longe como você pode possivelmente ir, sem encher a máquina, quer unidades de execução ou registros Você está basicamente fazendo mais multiplica em geral, em ordem Para obter menos cadeias de múltiplos e subtrai no crítico Caminho Ignorando de avg i-2 para avg i é fácil, você provavelmente pode fazer três e quatro Exatamente o quão longe depende do que sua máquina é, e quantos registros você have. And a latência do ponto flutuante somador e multiplicador Ou, melhor E, se o MADD ou MSUB tem 7 ciclos de comprimento, você pode fazer até 6 outros cálculos em sua sombra, mesmo se você tiver apenas um único flutuante Unidade de ponto Totalmente pipeline E assim por diante Menos se pipelined cada ciclo de otherr, como é comum para a dupla precisão em chips e GPUs mais velhos O código de montagem deve ser software pipelined de modo que iterações de loop diferente se sobrepõem Um bom compilador deve fazer isso para você, Tem que reescrever o código C para obter o melhor desempenho. Por a maneira que eu não quero sugerir que você deve criar uma matriz de avg Em vez disso, você precisaria de duas médias se avg i é calculado em termos de avg i-2, E assim por diante Você pode usar uma matriz de avg i se yo Você quer, mas eu acho que você só precisa ter 2 ou 4 avgs, chamado, criativamente, avg0 e avg1 2, 3, e girá-los. Este tipo de truque, dividindo um acumulador ou média em dois ou mais, combinando vários estágios Da recorrência, é comum em código de alto desempenho. Oh, sim precalculate ss, etc Se eu fiz isso direito, em precisão infinita isso seria idêntico Verifique-me, por favor. No entanto, em precisão finita FP seus resultados podem diferir, Espero que apenas ligeiramente, por causa de arredondamentos diferentes Se o desenrolamento é correto e as respostas são significativamente diferentes, você provavelmente tem um algoritmo numericamente instável Você é a pessoa que wouyld saber. Note flutuante arredondamento erros irá mudar os bits de baixo da sua resposta Tanto porque De rearranjar o código, e usando MADD eu acho que é provavelmente ok, mas você tem que decidir. Note os cálculos para avg i e avg i-1 são agora independentes Então você pode usar um conjunto de instruções SIMD, como o Intel SSE2, que permite Operação em dois 64 Bit valores em um registro de 128 bits de largura em um tempo Que vai ser bom para quase 2X, em uma máquina que tem bastante ALUs. If você tem registros suficientes para reescrever avg i em termos de avg i-4 e tenho certeza que você faz em IA64, então você pode ir 4X de largura, se você tiver acesso a uma máquina como 256 bit AVX. On uma GPU você pode ir para recorrências mais profundas, reescrever avg i em termos de avg i-8, e assim por diante. Algumas GPUs têm instruções Que calculam AX B ou mesmo AX BY como uma única instrução Embora isso é mais comum para 32 bits do que para precisão de 64 bits. Em algum ponto eu provavelmente começaria a perguntar que você quer fazer isso em vários preços de cada vez Não só isso Ajudá-lo com multithreading, ele também irá atender a correr em uma GPU E usando amplas SIMD. Minor tarde Addition. I estou um pouco constrangido não ter aplicado Horner s Rule para expressões like. slightly mais eficiente resultados ligeiramente diferentes com arredondamento. Minha defesa, qualquer compilador decente deve fazer isso por você. Mas a regra de Hrner faz com que a cadeia de dependência dee Por em termos de multiplicações Você pode precisar para desenrolar e pipelined o loop mais algumas vezes Ou você pode fazer. que você precalculate. I sei que isso é possível com o impulso como per. But eu realmente gostaria de evitar usar o impulso eu tenho googled e Não encontrei qualquer exemplos adequados ou legíveis. Basicamente eu quero acompanhar a média móvel de um fluxo em curso de um fluxo de números de ponto flutuante usando os mais recentes números 1000 como uma amostra de dados. Qual é a maneira mais fácil de conseguir this. I experimentou com Usando uma matriz circular, média móvel exponencial e uma média móvel mais simples e descobriu que os resultados da matriz circular adequados às minhas necessidades melhores. 38. Se suas necessidades são simples, você pode tentar usar um movimento exponencial Simplesmente, você faz uma variável de acumulador, e como seu código olha para cada amostra, o código atualiza o acumulador com o novo valor Você escolhe uma alfa constante que está entre 0 e 1, e calcula this. You só precisa encontrar Um valor de alph Um onde o efeito de uma determinada amostra dura apenas cerca de 1000 amostras. Hmm, eu realmente não tenho certeza que isso é adequado para você, agora que eu colocá-lo aqui O problema é que 1000 é uma janela muito longa para uma média móvel exponencial Eu não tenho certeza se há um alfa que iria espalhar a média sobre os últimos 1000 números, sem underflow no cálculo do ponto flutuante Mas se você queria uma média menor, como 30 números ou assim, esta é uma maneira muito fácil e rápido de fazer It. answered Jun 12 12 at 4 44. 1 em seu post A média móvel exponencial pode permitir que o alfa seja variável Assim isso permite que ele seja usado para calcular médias de base de tempo por exemplo, bytes por segundo Se o tempo desde a última atualização do acumulador é mais Do que 1 segundo, você deixa o alfa ser 1 0 De outra maneira, você pode deixar o alfa ser usecs desde a última atualização 1000000 jxh 12 de junho 12 em 6 21.Basicamente eu quero seguir a média movente de um córrego em curso de um córrego de números do ponto flutuando usando Os mais recentes números de 1000 como uma amostra de dados. Nota t O abaixo atualiza o total como elementos como substituto adicionado, evitando costoso ON traversal para calcular a soma - necessária para a média - on demand. Total é feito um parâmetro diferente de T para suportar, por exemplo, usando um longo longo quando totalizando 1000 long s, Um int para char s, ou um double to total flutuante s. This é um pouco falho em que numsamples poderia ir passado INTMAX - se você se importa você poderia usar um unsigned long long ou usar um extra bool dados membro para gravar quando o recipiente é Primeiro preenchido enquanto ciclismo numsamples em torno da matriz melhor então renomeado algo inócuo como pos. answered 12 de junho 12 em 5 19.um presume que void operador T amostra é realmente void operador T amostra oPless Jun 8 14 em 11 52. oPless ahhh bem manchado na verdade Eu quis dizer para que seja vazio operador T amostra, mas é claro que você poderia usar qualquer nota que você gostava Will fix, graças Tony D Jun 8 14 at 14 27C algoritmo para zero-latência exponencial média móvel. Last Modified 2012-08-13.Estou tentando implementar um baixo Corte de freqüência em c que essencialmente leva um fluxo de números e suaviza a saída de filtragem de jitter de alta freqüência de movimento, no entanto, é importante que os números ponderados dianteiros são considerados imediatamente como os dados é tempo crítico é controlar uma base de simulação de movimento usando a saída A partir de um pouco de software de jogo eu tenho um algoritmo de média móvel ponderada de trabalho, mas poderia fazer com algo um pouco mais responsivo no front-end, e eu encontrei este. O pseudo-código lá é como follows. Inputs Preço NumericSeries, Period NumericSimple Variáveis Fator 0, lag 0.if CurrentBar 1 então começa ZLEMA Fator de preço 2 Período 1 atraso Período-1 2 fim mais começam ZLEMA fator 2 Preço-preço defasagem 1-fator ZLEMA 1 end. I traduzido em C e meu código é Como segue. No entanto, ele doesn t parecem se comportar bastante como eu d espero Parece estar quase lá, mas às vezes eu recebo um valor ligeiramente menor do que todos os itens na fila quando eles são todos mais elevados. Minha fila eo número de itens em Ele é Passado como parâmetros, com o mais recente estar na frente em todos os momentos, também passar um contador de incremento a partir de 0 como exigido pela função. Não tenho certeza que eu interpretei o significado de ZLEMA 1 corretamente como ele não está claro em Seu pseudocódigo, então eu pensei que isso seria a última chamada s zlema e também estou supondo que Preço realmente significa Preço 0 Talvez eu tenho este errado. Am eu deveria estar copiando os valores zlema reais calculados de volta à minha fila original antes do Próxima chamada Eu não mudo a fila original em tudo diferente de apenas deslocando todos os valores um para o fim e inserindo o mais recente no início O código que eu uso para fazer isso é. Seria extremamente grato se alguém com uma melhor compreensão da matemática Poderia por favor sanidade verificar isso para mim para ver se eu tenho qualquer coisa ligeiramente errada. Graças tanto com antecedência se você pode help. Firstly graças a todos por sua entrada, muito appreciated. That faz sentido eu acho, então eu suponho, então, o melhor que eu Pode esperar é simplesmente um exponenti Aceitando que haverá um pequeno atraso, mas isso será minimizado pela ponderação mais pesada do que dada na média móvel ponderada tipicamente. Eu tenho este algoritmo também, mas um problema semelhante em que os valores não parecem muito corretos, a menos que isso É a natureza da fórmula. Por exemplo, digamos que minha matriz contém 16 valores, todos 0 4775 - a saída é 0 4983, mas eu esperava que fosse 0 4775.Faz este olhar certo para você. Exponencial Movendo Média flutuante ema flutuante vals, int numVals, int currentSample estático fator flutuante 0 estático float lastema 0 flutuante ema. if correnteSample 1 ema vals 0 fator 2 0 flutuante numVals 1 0 mais factor ema vals 0 1 0 - factor lastema lastema ema. Return ema Por outro lado, às vezes a saída é menor do que cada uma das entradas, mesmo se todos são higher. It é chamado da mesma forma como zlema acima, com um contador de incremento A fórmula e pseudocódigo para este aqui - Obrigado Mais uma vez, desculpas por meu mal-entendido de alguns dos fundamentos Atenciosamente, Chris J. Para o código que eu postei, você está certo sobre a situação do tamanho da matriz Isso deve ser facilmente corrigido Quanto às suas perguntas.1 A constante do filtro representa um corte de freqüência Eu usei um Digital Signal Processing DSP para esta técnica ki Low-pas sfilter é uma explicação simples Você quer a seção Discrete-Time Realization No meu caso, o A é a RC-Constant eles falam Então a freqüência que ele corta é acima 1 2 pi A Se você não tem uma compreensão da teoria de domínio de freqüência, isso pode ficar complicado. No seu caso, quanto mais alto você faz A, menor a freqüência que este filtro permitirá, o que significa que irá suavizar a curva mais E mais Quanto mais baixo você fizer isso, mais ruído que é permitido no sistema Lembre-se A deve maior ou igual a 1 para ser effective. I voltou a ligar o XLS novamente, desta vez sem os números mudando rand Ajustar a constante A e assistir Como suaviza ou filtra as variações de alta freqüência.2 O último ponto da matriz de entrada tem o valor mais recente.3 O mesmo é verdadeiro para a matriz de saída O último é o valor mais recente.5 O NUMVALS é arbitrário Você pode continuamente Adicionar à matriz de entrada e saída quantas vezes você gostaria e ele wouldn t efeito do filtro Em particular, eu usei 49 pontos Mas eu posso facilmente apagar os últimos 20 e as primeiras 29 saídas permaneceriam o mesmo A função não é Com base em quantos pontos estão sendo usados. Gostaria Para mencionar que eu desenvolvi esta função para uma conversão de uma só vez Se você queria fazer uma conversão para o próximo valor sobre a voar, você poderia tentar algo mais simples como anexado Novamente eu rusty em c Espero que este é direito A única coisa que você iria Necessidade de fornecer é a constante de entrada e filtro. Deixe-me saber se isso ajuda.
Comments
Post a Comment