Implementazioni alternative di funzioni/approcci standard - pagina 11

 
Nikolai Semko:
Puoi mandarmi il link per favore?

Non l'ha tenuto. Menzionato sul forum qui. Ho cercato io stesso nei motori di ricerca.

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

Non l'ha tenuto. Menzionato sul forum qui. Ho cercato io stesso nei motori di ricerca.

L'ho visto. È tutto molto primitivo senza la miscelazione dei colori dei pixel.
È solo che tutto quello che ho trovato sui forum era a livello di scuola materna. E sono già in quinta elementare.
 
Nikolai Semko:
È solo che tutto quello che ho incontrato sui forum era di livello elementare. E sono già in quinta elementare.

Ovviamente, tutte queste moto sono state ricostruite molte volte. Sono stati pubblicati persino dei libri, fino alle implementazioni asm.

Al giorno d'oggi le basi sono difficili da trovare, dato che quasi tutti usano API rilevanti per tutte le occasioni.

Quindi devi solo registrarti sui forum e chiedere in giro.

 
fxsaber:

Ovviamente, tutte queste moto sono state ricostruite molte volte. Sono stati pubblicati persino dei libri, fino alle implementazioni asm.

Ora le basi sono difficili da trovare, dato che quasi tutti usano API rilevanti per tutte le occasioni.

Quindi devi solo registrarti sui forum e chiedere.

Questo è il punto: è difficile. Comunque, non sono riuscito a trovarlo. Forse non stavo cercando abbastanza. Sui forum, tutti ti mandano alle librerie standard chiuse e si chiedono perché ne hai bisogno, quando tutto è disponibile. Certo, non mi preoccuperei se scrivessi in Java, JavaScript e simili. o se il mercato non fosse necessario.
Ok, sono già abituato ad essere orgogliosamente solo in questa faccenda per ora. Continuerò, inoltre, non ho praticamente nessun punto vuoto nella comprensione di quasi tutte le implementazioni in questa direzione. E d'altra parte ho acquisito alcune abilità uniche.
 
pavlick_:

Perché non usate LONG_MAX/MIN? Sarebbe più bello in qualche modo. Ha un bell'aspetto, credo. Ho fatto i tuoi test con gcc (con minime modifiche, naturalmente, il compilatore è molto vecchio 5.4.0, quello che avevo a portata di mano):


Beh, sì, non è bello. MaLONG_MAX= 9223372036854775807 è più di 9007199254740992. E la forma esadecimale di questo numero - 0x20000000000000 è rimproverata perché deve essere solo per il tipo ulong. Non so nemmeno come renderlo più chiaro. Non posso scrivere (ulong)(1<<53) perché è un'operazione che richiede tempo.

Il tipo double inizia a contenere interi senza parti frazionarie non a partire dal valoreLONG_MAX ma dalla massima mantissa possibile. Ma 53 bit sono permessi per la mantissa, cioè 2^53=9007199254740992.

pavlick_:

La tempistica del tuo codice fallisce - l'output è in milisecondi (non nano), e ancora non capisco perché abbiamo bisogno di meno t0.

t0 è il tempo di un ciclo completo di 1000000 passaggi della somma dei doppi primi

mentre t è il tempo dello stesso ciclo di somma degli stessi valori doppi, ma passati attraverso le funzioni ceil, ceil, round ecc.

Ho proceduto dalla logica che la differenza (t-t0) è il tempo netto speso per queste funzioni.

Naturalmente, una maggiore obiettività può essere raggiunta solo facendo diverse misurazioni.

- In nano calcolo sulla base del tempo impiegato per eseguire una funzione su 1.000.000. Esattamente in nano è corretto.

pavlick_:

Ho eseguito i tuoi test su gcc (con minime modifiche, naturalmente, il compilatore è molto vecchio 5.4.0, quello che era a portata di mano):

1. Compilazione con -O3.

2. Compilazione con -Ofast

Così si scopre. Che il codice MQL5 compilato gira più velocemente persino di Ofast? È difficile da credere, devi aver avuto un compilatore a 32 bit.
 
Nikolai Semko:

Non scrivere (ulong)(1<<53), poiché questa è già un'operazione che richiede tempo.

Questa operazione non richiede tempo, come tutte le operazioni con le costanti, comprese le stringhe.

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

Questa operazione è senza tempo come tutte le costanti, comprese le stringhe.

Wow - forte! Grazie. E ho pensato che conta ogni volta. Sì, beh, è logico, puoi già calcolarlo a tempo di compilazione.
Bene, questo è tutto allora:

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 ... Прервите скрипт, когда надоест ждать

Tuttavia, sarebbe più corretto scrivereDBL_MANT_DIG invece di 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 di guadagno minimo se tutti i valori del doppio sono frazionari.

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
File:
TestRound.mq5  11 kb
 
Nikolai Semko:
Così si scopre. Che il codice MQL5 compilato funziona più velocemente persino di Ofast? Trovo difficile credere che tu debba avere un compilatore a 32 bit.

Ho tolto il meno t0 da tutto (pensavo fosse un qualche tipo di errore) e il mio output ha tutto il ciclo misurato, non un singolo passaggio. Se convertiamo nella vostra forma di uscita in nanosecondi per iterazione (nella prima riga "Tempo di ciclo senza arrotondamento" - abbiamo lo stesso modo di contare), otteniamo:

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

Non c'è molta accelerazione su gcc (e ancora più lenta su -Ofast). Su mcc c'è un'accelerazione significativa a giudicare dal tuo test, ma:

avete 985'651 su 1'000'000 cioè quasi tutte le iterazioni soddisfano la condizione x < MIN || x > MAX.


-Ofast disabilita tutti i controlli inf/nan, l'impostazione di errno, cioè l'arrotondamento nudo sulla fpu è lasciato. E questo arrotondamento nudo non può essere sconfitto da un semplice confronto di x < MIN || x > MAX.

 
pavlick_:

Non c'è molta accelerazione su gcc (e ancora più lenta su -Ofast). Su µl è significativo.

Tuttavia, è difficile dirlo. Abbiamo buttato fuori t0 per delle belle cifre e abbiamo ottenuto 20 volte la differenza. Anche un minimo codice aggiuntivo sotto forma di ciclo (+t0) rende il risultato bello in diverse decine di volte a meno attraente in circa due volte. E cosa si può dire se non è solo un loop ma un vero algoritmo che fa qualcosa di utile? La differenza non sarà affatto visibile, vagherà da qualche parte molto dopo la virgola e difficilmente diventerà un collo di bottiglia. In un'applicazione reale il prelievo di mutex, le barriere della cpu, l'allocazione della memoria sono molto più costosi dell'arrotondamento. Tutto sommato, non ne vale la pena, imho.

 
pavlick_:

Sì, la differenza non sarà affatto visibile, sarà appesa da qualche parte molto dopo la virgola ed è improbabile che sia un collo di bottiglia. In un'applicazione reale prendere mutex, barriere di cpu, allocazione di memoria sono molto più costosi dell'arrotondamento. Tutto sommato, non ne vale la pena, imho.

Questo è vero il 99% delle volte, sì.

Prima di ottimizzare, bisogna assicurarsi di avere qualcosa da ottimizzare.

Nella mia pratica ricordo solo un caso in cui la mia implementazione di atof è stata davvero utile. Anche se mi sembrava che fosse così.

E si dovrebbe tenere a mente che qualsiasi ottimizzazione (tranne ***) non è gratuita.

Motivazione: