OK, ho parlato con un amico di compilatori e ottimizzazione dei programmi e ha suggerito che n * 0.5
è più veloce di n/2
. Ho detto che i compilatori fare questo tipo di ottimizzazione automatica, così ho scritto un piccolo programma per vedere se ci fosse una differenza tra n/2
e n * 0.5
:1.000.000.000 di calcoli per microsecondo?
Divisione:
#include <stdio.h>
#include <time.h>
int main(int argc, const char * argv[]) {
int i, m;
float n, s;
clock_t t;
m = 1000000000;
t = clock();
for(i = 0; i < m; i++) {
n = i/2;
}
s = (float)(clock() - t)/CLOCKS_PER_SEC;
printf("n = i/2: %d calculations took %f seconds (last calculation = %f)\n", m, s, n);
return 0;
}
Moltiplicazione:
#include <stdio.h>
#include <time.h>
int main(int argc, const char * argv[]) {
int i, m;
float n, s;
clock_t t;
m = 1000000000;
t = clock();
for(i = 0; i < m; i++) {
n = i * 0.5;
}
s = (float)(clock() - t)/CLOCKS_PER_SEC;
printf("n = i * 0.5: %d calculations took %f seconds (last calculation = %f)\n", m, s, n);
return 0;
}
E per entrambe le versioni ho ottenuto avg 0.000002s. quando compilato con clang main.c -O1
. E ha detto che ci deve essere qualcosa di sbagliato nella misurazione del tempo. Così ha poi scritto un programma:
#include <cstdio>
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
clock_t ts, te;
double dT;
int i, m;
double n, o, p, q, r, s;
m = 1000000000;
cout << "Independent calculations:\n";
ts = clock();
for (i = 0; i < m; i++)
{
// make it a trivial pure float calculation with no int casting to float
n = 11.1/2.3;
o = 22.2/2.3;
p = 33.3/2.3;
q = 44.4/2.3;
r = 55.5/2.3;
s = 66.6/2.3;
}
te = clock();
dT = ((float)(te - ts))/CLOCKS_PER_SEC; // make initial call to get the elapsed time to run the loop
ts = clock();
printf("Division: %d calculations took %f seconds\n", m, dT);
for (i = 0; i < m; i++)
{
// make it a trivial pure float calculation with no int casting to float
n = 11.1 * 0.53;
o = 22.2 * 0.53;
p = 33.3 * 0.53;
q = 44.4 * 0.53;
r = 55.5 * 0.53;
s = 66.6 * 0.53;
}
te = clock();
dT = ((float)(te - ts))/CLOCKS_PER_SEC; // make initial call to get the elapsed time to run the loop
ts = clock();
printf("Multiplication: %d calculations took %f seconds\n", m, dT);
cout << "\nDependent calculations:\n";
for (i = 0; i < m; i++)
{
// make it a trivial pure float calculation with no int casting to float
n = 11.1/2.3;
o = n/2.3;
p = o/2.3;
q = p/2.3;
r = q/2.3;
s = r/2.3;
}
te = clock();
dT = ((float)(te - ts))/CLOCKS_PER_SEC; // make initial call to get the elapsed time to run the loop
ts = clock();
printf("Division: %d calculations took %f seconds\n", m, dT);
for (i = 0; i < m; i++)
{
// make it a trivial pure float calculation with no int casting to float
n = 11.1 * 0.53;
o = n * 0.53;
p = o * 0.53;
q = p * 0.53;
r = q * 0.53;
s = r * 0.53;
}
te = clock();
dT = ((float)(te - ts))/CLOCKS_PER_SEC; // make initial call to get the elapsed time to run the loop
ts = clock();
printf("Multiplication: %d calculations took %f seconds\n", m, dT);
return 0;
}
E per questo ha ottenuto ...
1.869570s
1.868254s
25.674016s
3.497555s
... in questo ordine.
Così ho eseguito il programma sulla mia macchina compilato con clang++ main.cpp -O1
e ho ottenuto risultati simili come prima: 0.000002 to 0.000011
.
Tuttavia, quando ho compilato il programma senza ottimizzazione, ho ottenuto risultati simili a lui al suo primo test. Quindi la mia domanda è: come può una qualsiasi quantità di ottimizzazione rendere il programma quello molto più veloce?
quindi ci sono alcuni problemi seri con i vostri programmi di riferimento. Ciò spezzerà comunque qualsiasi cosa tu stia cercando di testare. In particolare, stai mescolando i tipi e hai una coercizione di tipo che è MOLTO costosa in sé e per sé (e potrebbe essere ciò a cui si riferiva il tuo amico). Inoltre non c'è nulla qui che un compilatore non possa calcolare in fase di compilazione. – Mgetz
'n = i * 0.5;' promuove 'i' a' double', moltiplicato per .5 e riconvertito in 'float'. 'n = i/2;' divide (probabilmente cambia) 'i' per 2, quindi converte in double. Non stai testando la moltiplicazione e la divisione, ma le operazioni non correlate. –
Se vuoi che i tuoi "benchmark" non vengano ottimizzati, prova ad accumulare il risultato all'interno di ogni iterazione nella variabile 's'. Quindi stampa il valore finale di 's' dopo aver effettuato il calcolo del tempo. – Praetorian