ОК, я говорил с другом о компиляторах и оптимизации программ, и он предположил, что n * 0.5
быстрее, чем n/2
. Я сказал, что компиляторы такого рода оптимизации автоматически, поэтому я написал небольшую программу, чтобы увидеть, есть ли разница между n/2
и n * 0.5
:1 000 000 000 вычислений на микросекунду?
Раздел:
#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;
}
Умножение:
#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;
}
И для обеих версий я получил 0.000002s avg. при компиляции с clang main.c -O1
. И он сказал, что должно быть что-то не так с измерением времени. Таким образом, он тогда написал программу:
#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;
}
И для этого он получил ...
1.869570s
1.868254s
25.674016s
3.497555s
... в таком порядке.
Итак, я запустил программу на своей машине, составленную с помощью clang++ main.cpp -O1
, и получил аналогичные результаты: 0.000002 to 0.000011
.
Однако, когда я скомпилировал программу без оптимизации, я получил с ним аналогичные результаты в своем первом тесте. Поэтому мой вопрос в том, как может любая оптимизация сделать программу тем, что намного быстрее?
так что есть некоторые серьезные проблемы с вашими тестовыми программами. В любом случае это сломает все, что вы пытаетесь проверить. Наиболее заметно, что вы смешиваете типы и имеете тип слияния, в котором ОЧЕНЬ дорого и само по себе (и может быть то, о чем говорил ваш друг). Кроме того, компилятор не может рассчитывать во время компиляции. – Mgetz
'n = i * 0.5;' продвигает 'i' на' double', multplies на .5 и преобразует обратно в 'float'. 'n = i/2;' делит (вероятно, сдвигает) 'i' на 2, а затем преобразует в double. Вы не тестируете умножение и разделение, но не связанные с ним операции. –
Если вы хотите, чтобы ваши «контрольные показатели» не были оптимизированы, попробуйте накопить результат на каждой итерации в переменной 's'. Затем напечатайте окончательное значение 's' после того, как вы сделали расчет времени. – Praetorian