Implementações alternativas de funções/abordagens padrão - página 11

 
Nikolai Semko:
Você pode, por favor, me enviar o link?

Não o guardou. Mencionado no fórum aqui. Eu mesmo procurei nos motores de busca.

Вопрос к сообществу программистов по поводу авторства
Вопрос к сообществу программистов по поводу авторства
  • 2017.11.24
  • www.mql5.com
Общее обсуждение: Вопрос к сообществу программистов по поводу авторства
 
fxsaber:

Não o guardou. Mencionado no fórum aqui. Eu mesmo pesquisei através dos motores de busca.

Eu já vi isso. É tudo muito primitivo sem mistura de cores pixel.
É que tudo o que eu encontrei nos fóruns foi a nível de jardim de infância. E eu já estou na 5ª série.
 
Nikolai Semko:
É que tudo o que encontrei nos fóruns era a nível de jardim de infância. E eu já estou na 5ª série.

Obviamente, todas estas bicicletas foram reconstruídas muitas vezes. Até mesmo os livros foram publicados, até mesmo as implementações asm.

Hoje em dia, o básico é difícil de encontrar, pois quase todos usam APIs relevantes para todas as ocasiões.

Portanto, você só tem que se registrar nos fóruns e perguntar por aí.

 
fxsaber:

Obviamente, todas estas bicicletas foram reconstruídas muitas vezes. Até mesmo livros foram publicados, até e incluindo implementações de asm.

Agora o básico é difícil de encontrar, já que quase todos usam APIs relevantes para todas as ocasiões.

Portanto, você só tem que se registrar nos fóruns e perguntar.

O problema é esse: é difícil. De qualquer forma, não consegui encontrá-lo. Talvez eu não estivesse procurando o suficiente. Nos fóruns, todos o enviarão para as bibliotecas fechadas padrão e se perguntarão por que você precisa, quando tudo estiver disponível. É claro, eu não preocuparia minha cabeça se escrevesse em Java, JavaScript e similares. ou se o mercado não fosse necessário.
Ok, já estou acostumado a estar orgulhosamente sozinho neste assunto, por enquanto. Continuarei, além disso, não tenho praticamente nenhum ponto em branco na compreensão de quase nenhuma implementação nesta direção. E, por outro lado, adquiri algumas habilidades únicas.
 
pavlick_:

Por que você não usa LONG_MAX/MIN? De alguma forma, ficaria mais bonito. Acho que fica bonito. Joguei seus testes com o gcc (com modificações min, é claro, o compilador é muito antigo 5.4.0, o que eu tinha em mãos):


Bem, sim, não é agradável. MasLONG_MAX= 9223372036854775807 é mais de 9007199254740992. E a forma hexadecimal deste número - 0x20000000000000 é repreendida porque deve ser apenas para o tipo ulong. Eu nem sei como torná-lo mais claro. Eu não posso escrever (ulong)(1<<53) porque é uma operação demorada.

O tipo duplo começa a conter inteiros sem partes fracionadas não a partir do valorLONG_MAX, mas a partir do máximo possível de mantissa. Mas 53 bits são permitidos para a mantissa, ou seja, 2^53=9007199254740992.

pavlick_:

Seu código de tempo falha - a saída é em milissegundos (não nano), e eu ainda não entendo porque precisamos de menos t0.

t0 é o tempo de ciclo completo de 1000000 passes de soma do duplo principal

enquanto t é o tempo do mesmo ciclo de soma dos mesmos valores duplos, mas passou por funções ceil, ceil, round etc.

Parti da lógica de que a diferença (t-t0) é o tempo líquido gasto com estas funções.

Naturalmente, uma maior objetividade só pode ser alcançada através de várias medidas.

- Em nano, eu calculo com base no tempo necessário para realizar uma função em 1.000.000. Exatamente em nano está correto.

pavlick_:

Eu fiz seus testes no gcc (com modificações mínimas, é claro, o compilador é muito antigo 5.4.0, o que estava à mão):

1. Compilação com -O3.

2. Compilação com -Ofast

Assim acontece. Que o código MQL5 compilado funciona mais rápido que até mesmo o Ofast? É difícil de acreditar. Você deve ter tido um compilador de 32 bits lá.
 
Nikolai Semko:

Não escreva (ulong)(1<<53), porque essa já é uma operação demorada.

Esta operação não consome muito tempo, como todas as operações com constantes, incluindo as cordas.

input long l = (ulong)1 << 53;
input string s = (string)__DATETIME__ + __FILE__;
 
fxsaber:

Esta operação é intemporal como todas as constantes, incluindo as cordas.

Uau - legal! Obrigado. E eu achava que isso contava sempre. Sim, bem, é lógico, você já pode calculá-lo em tempo de compilação.
Bem, então é isso:

double Ceil (double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}
2018.08.26 18:04:07.638 TestRound (EURUSD,M1)   Время цикла без округления = 1.302 наносекунд, сумма = 115583114403605978808320.00000000
2018.08.26 18:04:07.642 TestRound (EURUSD,M1)   Время выполнения функции ceil =  2.389 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.644 TestRound (EURUSD,M1)   Время выполнения функции Ceil =  0.223 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.648 TestRound (EURUSD,M1)   Время выполнения функции floor = 2.884 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.649 TestRound (EURUSD,M1)   Время выполнения функции Floor = 0.122 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.654 TestRound (EURUSD,M1)   Время выполнения функции round = 3.413 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.656 TestRound (EURUSD,M1)   Время выполнения функции Round = 0.222 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.656 TestRound (EURUSD,M1)   Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать

Entretanto, seria mais correto escreverDBL_MANT_DIG ao invés de 53

double Ceil (double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}

Caso de ganho mínimo se todos os valores de duplo forem fracionários.

2018.08.26 18:20:35.408 TestRound (EURUSD,M1)   Время выполнения функции sqrt = 1.083 наносекунд, сумма = 81969849.90928555
2018.08.26 18:20:35.413 TestRound (EURUSD,M1)   Время выполнения функции ceil =  3.579 наносекунд, Контрольная сумма = 5250492895.0
2018.08.26 18:20:35.416 TestRound (EURUSD,M1)   Время выполнения функции Ceil =  1.249 наносекунд, Контрольная сумма = 5250492895.0
2018.08.26 18:20:35.422 TestRound (EURUSD,M1)   Время выполнения функции floor = 3.931 наносекунд, Контрольная сумма = 5249492896.0
2018.08.26 18:20:35.424 TestRound (EURUSD,M1)   Время выполнения функции Floor = 0.513 наносекунд, Контрольная сумма = 5249492896.0
2018.08.26 18:20:35.427 TestRound (EURUSD,M1)   Время выполнения функции round = 1.519 наносекунд, Контрольная сумма = 5249992896.0
2018.08.26 18:20:35.429 TestRound (EURUSD,M1)   Время выполнения функции Round = 0.571 наносекунд, Контрольная сумма = 5249992896.0
Arquivos anexados:
TestRound.mq5  11 kb
 
Nikolai Semko:
Assim acontece. Que o código MQL5 compilado funciona mais rápido que até mesmo Ofast? Acho difícil de acreditar que você deve ter tido um compilador de 32 bits.

Eu tirei o menos t0 de tudo (pensei que fosse algum tipo de erro) e minha saída tem todo o laço medido, não um único passe. Se convertermos para sua forma de produção em nanossegundos por iteração (na primeira linha "Tempo de ciclo sem arredondamento" - temos a mesma forma de contagem), obtemos:

-O3
Время цикла без округления = 1.099 наносекунд, сумма = 1.15583114 e+23
-Ofast
Время цикла без округления = 0.552 наносекунд, сумма = 1.15583114 e+23

Não há muita aceleração no gcc (e ainda mais lenta no -Ofast). Na mcc há uma velocidade significativa, a julgar pelo seu teste, mas:

você tem 985'651 de 1'000'000, ou seja, quase todas as iterações satisfazem a condição x < MIN || x > MAX.


-Ofast desabilita todas as verificações inf/nan, errno setting, ou seja, o arredondamento nu no fpu é deixado. E este arredondamento nu não pode ser derrotado por uma simples comparação de x < MIN || x > MAX.

 
pavlick_:

Não há muita aceleração no gcc (e ainda mais lenta no -Ofast). Em µl é significativo.

No entanto, é difícil dizer. Jogamos fora t0 por bons números e conseguimos 20 vezes a diferença. Mesmo o código adicional mínimo em forma de laço (+t0) torna o resultado bonito em várias dezenas de vezes a menos atraente em cerca de duas vezes. E o que você pode dizer se não for apenas um loop, mas um algoritmo real fazendo algo útil? A diferença não será visível de forma alguma, ela irá vaguear em algum lugar muito depois do ponto decimal e dificilmente se tornará um gargalo de estrangulamento. Em uma aplicação real a captação mutex, barreiras cpu, alocação de memória são muito mais caras do que o arredondamento. Em suma, não vale a pena apostar, imho.

 
pavlick_:

Sim, a diferença não será visível de forma alguma, ficará em algum lugar muito depois do ponto decimal e é improvável que seja um gargalo de estrangulamento. Em uma aplicação real, que toma barreiras mutex, cpu, a alocação de memória é muito mais cara do que o arredondamento. Em suma, não vale a pena apostar, imho.

Isto é verdade em 99% das vezes, sim.

Antes de otimizar, você deve certificar-se de ter algo a ser otimizado.

Em minha prática eu me lembro apenas de um caso quando minha própria implementação do atof realmente ajudou. Embora me parecesse que sim.

E você deve ter em mente que qualquer otimização (exceto ***) não é livre.