Thursday 21 December 2017

Exponencial móvel média c código


Tenho perfilado isso usando o Visual C profiler, e ele representa cerca de 35 do tempo de execução. Esta média móvel exponencial é chamada mais de um trilhão de vezes, porque é usada repetidamente no processamento de mais de 400 gigabytes de dados. Os dados estão saindo de uma matriz de disco de estado sólido Raid Level 0, portanto, 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 quanto possível dos dados. Então eu era capaz de aumentá-lo novamente por um fator de ndash PaeneInsula Oct 30 11 at 20:41 Eu era capaz de aumentar a velocidade novamente por um fator de 12 por multithreading-lo (a natureza dos dados é tal que pode ser multithreaded em De tal forma que a carga é perfeitamente equilibrada.) E eu tenho que correr em um i7 990x (que tem 6 núcleos, hyperthreaded de um total de 12), overclock. Ndash PaeneInsula Oct 30 11 at 20:51 Claro, multithreading pode ajudar. Mas você pode quase certamente melhorar o desempenho em uma única máquina threaded. Primeiro, você está calculando 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 passos de unidade. I. e. Mudar a direção da matriz para que você digitalizar de baixo para alto, em vez de alta a baixa é quase sempre melhor. Em seguida, reescrevendo um pouco - por favor, permita-me encurtar os nomes das variáveis ​​para torná-lo mais fácil de digitar: By the way, vou começar a usar os atalhos p para o preço e s para suavização, para salvar a digitação. Sou preguiçosa. Mas é provavelmente mais rápido para fazer A latência entre avgi e avgi-2 é então 1 multiplicar e um adicionar, em vez de uma subtração e uma multiplicação entre avgi e avgi-1. I. e. Mais de duas vezes mais rápido. Em geral, você deseja reescrever a recorrência para que avgi seja calculado em termos de avgj para j, desde que possivelmente possa ir, sem encher a máquina, unidades de execução ou registradores. Você basicamente está fazendo mais multiplicações em geral, a fim de obter menos cadeias de múltiplos (e subtrai) no caminho crítico. Passar de avgi-2 para avgi é fácil, você provavelmente pode fazer três e quatro. Exatamente até que ponto depende do que sua máquina é, e quantos registros você tem. E a latência do sumador de ponto flutuante e multiplicador. Ou, melhor ainda, o sabor da combinação multi-adicionar instrução que você tem - todas as máquinas modernas tê-los. Por exemplo. 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 uma única unidade de ponto flutuante. Totalmente pipeline. E assim por diante. Menos se pipelined cada ciclo do otherr, como é comum para a precisão dobro em microplaquetas e em GPUs mais velhas. 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ê, mas você pode ter que reescrever o código C para obter o melhor desempenho. By the way: eu não quero sugerir que você deve estar criando uma matriz de AVG. Em vez disso, você precisaria de duas médias se avgi é calculado em termos de avgi-2, e assim por diante. Você pode usar uma matriz de avgi se você quiser, mas eu acho que você só precisa ter 2 ou 4 avgs, chamado, criativamente, avg0 e avg1 (2, 3.), e girá-los. Esse tipo de truque, dividindo um acumulador ou média em dois ou mais, combinando vários estágios da recorrência, é comum no código de alto desempenho. Oh, sim: precalculate ss, etc. Se eu tiver feito 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 está correto e as respostas são significativamente diferentes, você provavelmente tem um algoritmo numericamente instável. Você é aquele que deveria saber. Nota: os erros de arredondamento de ponto flutuante alteram os bits mais baixos da sua resposta. Ambos por causa de rearranjar o código, e usando MADD. Acho que isso provavelmente está bem, mas você tem que decidir. Nota: os cálculos para avgi e avgi-1 são agora independentes. Assim, você pode usar um conjunto de instruções SIMD, como o Intel SSE2, que permite a operação em dois valores de 64 bits em um registro de 128 bits de largura por vez. Thatll ser bom para quase 2X, em uma máquina que tem ALUs suficiente. Se você tem registros suficientes para reescrever avgi em termos de avgi-4 (e tenho certeza que você faz no iA64), então você pode ir 4X de largura, se você tiver acesso a uma máquina como 256 bits AVX. Em uma GPU. Você pode ir para recorrências mais profundas, reescrevendo avgi em termos de avgi-8, e assim por diante. Algumas GPUs têm instruções que calculam AXB ou mesmo AXBY como uma única instrução. Embora isso seja mais comum para 32 bits do que para precisão de 64 bits. Em algum momento, eu provavelmente começaria a perguntar: você quer fazer isso em vários preços ao mesmo tempo Isso não só ajudá-lo com multithreading, ele também irá atender a correr em uma GPU. E usando SIMD de largura. Minor Late Addition Estou um pouco constrangido não ter aplicado Horners Rule para expressões como um pouco mais eficiente. Resultados ligeiramente diferentes com o arredondamento. Na minha defesa, qualquer compilador decente deve fazer isso por você. Mas a regra de Hrners torna a cadeia de dependência mais profunda em termos de multiplicações. Você pode precisar desenrolar e pipelined o loop algumas vezes mais. Ou você pode fazer onde você precalculateI sabe que isso é possível com o impulso como por: Mas eu realmente gostaria de evitar usar impulso. Eu tenho googled e não encontrei qualquer exemplos adequados ou legível. Basicamente, eu quero acompanhar a média móvel de um fluxo contínuo de um fluxo de números de ponto flutuante usando os números de 1000 mais recentes como uma amostra de dados. Qual é a maneira mais fácil de conseguir isso que eu experimentei com o uso de uma matriz circular, média móvel exponencial e uma média móvel mais simples e descobriu que os resultados da matriz circular adequado às minhas necessidades. Se suas necessidades são simples, você pode apenas tentar usar uma média móvel exponencial. Simplificando, 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 um alfa constante que está entre 0 e 1 e calcula isso: Você só precisa encontrar um valor de alfa onde o efeito de uma determinada amostra dura apenas cerca de 1000 amostras. Hmm, Im realmente não tenho certeza que isso é adequado para você, agora que Ive colocá-lo aqui. O problema é que 1000 é uma janela muito longa para uma média móvel exponencial Não tenho certeza se há um alfa que iria espalhar a média nos últimos 1000 números, sem subfluxo no cálculo de ponto flutuante. Mas se você quisesse uma média menor, como 30 números ou assim, esta é uma maneira muito fácil e rápida de fazê-lo. Respondeu 12 de junho 12 em 4:44 1 em seu borne. A média móvel exponencial pode permitir que o alfa seja variável. Portanto, isto permite que ele seja usado para calcular médias de base de tempo (por exemplo, bytes por segundo). Se o tempo desde a última actualização do acumulador for superior a 1 segundo, deixe alfa ser 1.0. Caso contrário, você pode deixar alfa ser (usecs desde a última atualização1000000). Ndash jxh 12 de junho de 12 às 6:21 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 de 1000 como uma amostra de dados. Observe que o abaixo atualiza o total como elementos como addedreplaced, evitando costal O (N) traversal para calcular a soma - necessária para a média - on demand. Total é feito um parâmetro diferente de T para suporte, e. Usando um longo longo quando totalizando 1000 s longos, um int para char s, ou um dobro ao total float s. Este é um pouco falho em que numsamples poderia ir passado INTMAX - se você se importa que você poderia usar um unsigned longa. Ou usar um membro de dados bool extra para gravar quando o recipiente é preenchido pela primeira vez enquanto ciclismo numsamples ao redor da matriz (melhor então renomeado algo inócuo como pos). Respondida em 12 de junho de 12 às 5:19, assume-se que o operador de quotvoid (amostra T) é realmente operador quotvoid (T amostra) quot. Ndash oPless Jun 8 14 at 11:52 oPless ahhh. Bem manchado. Na verdade, eu quis dizer para ser vazio operador () (T amostra), mas é claro que você poderia usar qualquer nota que você gostava. Will fix, obrigado. Ndash Tony D Jun 8 14 em 14: 27É possível implementar uma média móvel em C sem a necessidade de uma janela de amostras Ive descobri que eu posso otimizar um pouco, escolhendo um tamanho de janela thats um poder de dois para permitir bit - shifting em vez de dividir, mas não precisando de um buffer seria bom. Existe uma maneira de expressar um novo resultado da média móvel apenas como uma função do antigo resultado e da nova amostra Definir um exemplo de média móvel, através de uma janela de 4 amostras para ser: Adicionar nova amostra e: Uma média móvel pode ser implementada recursivamente , Mas para um cálculo exato da média móvel você deve se lembrar da amostra de entrada mais antiga na soma (ou seja, o a no seu exemplo). Para um comprimento N média móvel você calcula: onde yn é o sinal de saída e xn é o sinal de entrada. Eq. (1) pode ser escrito recursivamente como Então você sempre precisa lembrar a amostra xn-N para calcular (2). Como indicado por Conrad Turner, você pode usar uma janela exponencial (infinitamente longa), que permite calcular a saída somente da saída anterior e da entrada atual: mas esta não é uma média móvel padrão (não ponderada), mas uma média exponencial Ponderada média móvel, onde as amostras mais no passado obter um menor peso, mas (pelo menos em teoria) você nunca se esqueça nada (os pesos apenas ficar menor e menor para amostras no passado). Eu implementei uma média móvel sem memória de item individual para um programa de rastreamento GPS que eu escrevi. Eu começo com 1 amostra e dividir por 1 para obter o avg atual. Eu adiciono então uma outra amostra e divido por 2 à corrente avg. Isso continua até que eu chegar ao comprimento da média. Cada vez depois, eu adiciono na nova amostra, obter a média e remover essa média do total. Eu não sou um matemático, mas isso parecia ser uma boa maneira de fazê-lo. Eu imaginei que iria transformar o estômago de um cara de matemática real, mas, verifica-se que é uma das formas aceitas de fazê-lo. E funciona bem. Basta lembrar que quanto maior o seu comprimento, mais lento é seguir o que você deseja seguir. Isso pode não importar a maior parte do tempo, mas quando os satélites seguintes, se você é lento, a trilha poderia estar longe da posição real e vai ficar mal. Você poderia ter uma lacuna entre o sat e os pontos de arrasto. Eu escolhi um comprimento de 15 atualizado 6 vezes por minuto para obter alisamento adequado e não ficar muito longe da posição real sentado com os pontos de trilha suavizada. Respondida Nov 16 16 at 23:03 initialize total 0, count0 (cada vez vendo um novo valor Então uma entrada (scanf), um add totalnewValue, um incremento (count), uma divide average (totalcount) Todas as entradas Para calcular a média apenas nas últimas 4 entradas, seria necessário 4 variáveis ​​de entrada, talvez copiando cada entrada para uma variável de entrada mais antiga, calculando a nova média móvel como a soma das 4 variáveis ​​de entrada, dividida por 4 Bom se todos os insumos foram positivos para fazer o cálculo médio respondido Feb 3 15 at 4:06 Isso vai realmente calcular a média total e NÃO a média móvel. Como a contagem fica maior o impacto de qualquer nova amostra de entrada torna-se ndash nitidamente pequeno Hilmar fevereiro 3 15 at 13:53 Sua resposta 2017 Stack Exchange, IncIm no processo de criação de um algoritmo de negociação forex e queria tentar o meu tiro no cálculo EMA (Exponential Moving Averages). Meus resultados parecem estar corretos (em comparação com o calculatio Ns eu fiz à mão) então eu acredito que o método seguinte funciona, mas só queria ter um conjunto extra de olhos para faz com que im não faltando nada. Note que isso apenas retorna o EMA para o preço mais recente, ele não retorna uma matriz de EMAs como que não é o que eu preciso para o meu aplicativo. Recursão é uma boa ferramenta para o trabalho certo, mas aqui ele é usado para realizar loop simples. Como tal o código. É mais difícil de ler e raciocinar. É mais lento porque grande parte do código em ema só precisa ser executado uma vez. Irá falhar com o valor suficientemente grande da janela devido à pilha de chamadas Pythons transbordando. Por favor, documente pelo menos os parâmetros de cada função, por exemplo. Essa janela é o comprimento da janela, e essa posição conta para trás a partir do final dos dados. (Na verdade, as coisas seriam mais claras se a posição fosse um índice normal de forward em dados) Aumentar uma exceção quando você encontrar um parâmetro tem um valor inválido. Retornando Nenhum, em vez disso, só causará uma exceção mais confusa mais tarde. Na verdade, se eu tentar Indicators (). Ema (closeprices, 600) Recebo recursão infinita porque sma retorna None. Que faz ema chamar sma repetidamente. O ponto anterior também revela que se len (dados) lt janela 2 não é a verificação de validade direita. O 1 em data-window2 1: - window 1 não parece correto para mim. Suponho que você deseja data-window2: - window A declaração return previousema está em um lugar estranho porque naquele momento você calculou uma nova currentema. Este é o caso base da recursão, e é costume tratar o caso de base primeiro. Revisão pouco profunda: Você não precisa escrever uma aula para o que você está fazendo (e eu sugiro que você dê uma olhada neste vídeo). Sua classe não encapsula quaisquer dados e você apenas usá-lo para ter suas funções em uma mesma entidade. Eu acho que as coisas mais fáceis de entender se você fosse definir classmethod para tornar óbvio que você não vai realmente confiar em qualquer instância qualquer. No entanto, uma opção ainda melhor seria apenas definir funções em um módulo indicador. Resposta Obrigado pelas sugestões que eu realmente tê-los como classmethods e debatido indo e voltando entre mesmo usando uma classe ou apenas definir funções em um módulo indicador (que eu vou fazer agora). Ndash ChrisC Nov 25 14 em 19:12 Apenas assisti o vídeo também, grande coisa. Ndash ChrisC Nov 25 14 em 19:43 Sua resposta 2017 Stack Exchange, Inc

No comments:

Post a Comment