const double pi = 3.1415926535897;
static double mysin(double x) {
return ((((((-0.000140298 * x - 0.00021075890) * x + 0.008703147) * x -
0.0003853080) * x - 0.16641544) * x - 0.00010117316) * x +
1.000023121) * x;
}
static void Main(string[] args) {
Stopwatch sw = new Stopwatch();
double a = 0;
double[] arg = new double[1000000];
for (int i = 0; i < 1000000; i++) {
arg[i] = (pi/2000000);
}
sw.Restart();
for (int i = 0; i < 1000000; i++) {
a = a + Math.Sin(arg[i]);
}
sw.Stop();
double t1 = (double)(sw.Elapsed.TotalMilliseconds);
a = 0;
sw.Restart();
for (int i = 0; i < 1000000; i++) {
a = a + mysin(arg[i]);
}
sw.Stop();
double t2 = (double)(sw.Elapsed.TotalMilliseconds);
Console.WriteLine("{0}\n{1}\n", t1,t2);
Console.Read();
}
Questa serie di potenze è valida per [0, pi/2] ed è 10 volte più lenta della funzione sinusoidale incorporata in modalità di rilascio. 1 ms vs 10 ms.Perché il mio algoritmo seno è molto più lento del valore predefinito?
Tuttavia, quando copio il codice di scrittura mysin
nella funzione, ottengo praticamente la stessa ora di rilascio e il mio codice è circa 4 volte più veloce in modalità di debug.
a = 0;
sw.Restart();
for (int i = 0; i < 1000000; i++) {
double x = arg[i];
a = a + ((((((-0.000140298 * x - 0.00021075890) * x + 0.008703147) * x -
0.0003853080) * x - 0.16641544) * x - 0.00010117316) * x +
1.000023121) * x;
//a = a + mysin(arg[i]);
}
Qual è l'affare qui? Come faccio a rendere questo tipo di calcoli più veloce? Sto indovinando che il codice riconosce automaticamente che l'algoritmo sin non dovrebbe essere chiamato ma copia incolla nel ciclo. Come faccio a fare in modo che il compilatore faccia lo stesso per me.
Un'altra domanda, C++ farebbe la stessa ottimizzazione per la sua funzione sin/cos predefinita? Altrimenti, come farei per assicurarmi che lo faccia. Modifica: l'ho testato e la mia funzione seno (con 4 extra se le condizioni aggiunte per espandere il dominio su tutto il reale) viene eseguita circa il 25% più veloce (anche se imprecisa) rispetto alla funzione sin predefinita. E infatti, la versione incollata della copia è più lenta di quando la scrivo come una funzione separata.
Hai eseguito la build "Release" del tuo programma? In caso contrario, probabilmente la tua funzione non è in linea. – SuperOli
Intendi dire che quando si copia-incolla il codice nella funzione principale si ottiene lo stesso tempo con 'mysin' come' Math.Sin'? –
Sì, ottengo la stessa durata in modalità di rilascio. In modalità di debug, copia serie di potenze incollate è in realtà 4 volte più veloce. – grdgfgr