Есть блоки кода вычислений блок1, блок2, блок3, блок4,...блок 10, скажем. Скажите, как поступить при использовании их в цикле:
for (i = 0; i <= n; i++) {
блок1;
блок2;
блок3;
блок4;
...
блок10;
}
Или же так оптимально:
for (i = 0; i <= n; i++) {
блок1;
}
for (i = 0; i <= n; i++) {
блок2;
}
.............
for (i = 0; i <= n; i++) {
блок10;
}
Можете объяснить почему? Мне лично кажется, что первый вариант быстрый и правильный.
Ответ
Ответ скорее не ТС, а @IronVbuf. Начало развернутого комментирования его ответа. Копия моего комментария:
@IronVbif, рассуждения красивые. Время позднее, не хочу (сейчас) все разбирать.
Если правильно понял, в пунктах 4, 5 и 6 Вы склоняетесь к тому, что несколько маленьких циклов (особенно если их тела маленькие) будут производительней одного.
Практический замер (gcc -O3 MinGW (32-bit) Windows 7 64-bit I5-2500 3.3GHz) показал обратное (причем аж в 3 раза для 6 циклов и 10^9 повторов маленьких вычислений (преобразование int->double, double умножение и сложение)
Примерчик (нисколько не претендует на полноту, 5 минут на коленке).
gcc -O3 MinGW (32-bit) Windows 7 64-bit I5-2500 3.3GHz
#include
#define incvar(x,y) {x = x + i*y;}
main (int ac, char *av[])
{
double a = 0, b = 0, c = 0, d = 0, e = 0, f = 0;
int i;
if (av[1]) {
printf ("one loop
");
for (i = 0; i < 1000000000; i++) {
incvar(a,1.234);
incvar(b,7.234);
incvar(c,11.234);
incvar(d,111.234);
incvar(e,51.234);
incvar(f,21.234);
}
} else {
printf ("six loops
");
for (i = 0; i < 1000000000; i++)
incvar(a,1.234);
for (i = 0; i < 1000000000; i++)
incvar(b,7.234);
for (i = 0; i < 1000000000; i++)
incvar(c,11.234);
for (i = 0; i < 1000000000; i++)
incvar(d,111.234);
for (i = 0; i < 1000000000; i++)
incvar(e,51.234);
for (i = 0; i < 1000000000; i++)
incvar(f,21.234);
}
printf ("%e %e %e %e %e %e
",a,b,c,d,e,f);
}
c:/Users/avp/src/cc/hashcode $ gcc -O3 bloloops.c
c:/Users/avp/src/cc/hashcode $ date; ./a; date
Mon Aug 13 23:55:42 2012
six loops
6.170000e+017 3.617000e+018 5.617000e+018 5.561700e+019 2.561700e+019 1.061700e+019
Mon Aug 13 23:56:00 2012
c:/Users/avp/src/cc/hashcode $ date; ./a 1; date
Mon Aug 13 23:56:17 2012
one loop
6.170000e+017 3.617000e+018 5.617000e+018 5.561700e+019 2.561700e+019 1.061700e+019
Mon Aug 13 23:56:23 2012
c:/Users/avp/src/cc/hashcode $
Все желающие приглашаются к экспериментированию (вместо теоретизирования на основе прочитанной литературы) с последующим обсуждением результатов.
UPDATE
Для замера времени исполнения фрагментов программы удобно использовать функцию:
/*
avp
время в миллисекундах
*/
#include
long long
mtime()
{
struct timeval t;
gettimeofday(&t, NULL);
long long mt = (long long)t.tv_sec * 1000 + t.tv_usec / 1000;
return mt;
}
Меряем так:
...
long long mtime(void);
...
long long start = mtime();
// измеряемый код
...
printf ("duration: %lld msec
",mtime()-start);
...
Комментариев нет:
Отправить комментарий