LINUX.ORG.RU

Скорость вызова функций в C


0

0

В программе несколько однотипных функций, вычисляющих интеграл методом Симпсона.

double idens(double x,double y) {
        int steps,c; 
        double rn, sumn, sprev, steplength, extra;
    extra=2*dens(x,y,0.5);
    sumn=dens(x,y,0)+dens(x,y,1)+2*extra;
    steps=1;
    do {
         steps*=2; sprev=sumn; steplength=(1.0/steps/2); sumn-=extra; extra=0;
         for (c=0; c<steps; c++){ 
             extra+=dens(x,y,c*2+1)*steplength)*2; }
         sumn+=extra*2;
         rn=(sumn/6.0/steps-sprev/3.0/steps); 
         if (rn<0) {rn=-rn;};
    } while (rn>epsilon);
    return sumn;}

Различаются они только вызываемой подинтегральной функцией вида double dens(double x, double y, double z)

Вопрос: имеет ли смысл обозначить dens как переменную и заменить все интегрирующие функции на одну? Или это замедлит программу?

Заранее спасибо.
★★

Re: Скорость вызова функций в C

[offtop]Было бы неплохо сразу, при запуске, составить таблицу решений, а потом брать значения из неё, а не вычислять каждый раз новое значение в цикле.[/offtop]

anonymous ()

Re: Скорость вызова функций в C

> имеет ли смысл обозначить dens как переменную и заменить все интегрирующие функции на одну?

Имеет. Я вообще не очень понимаю, зачем тебе несколько разных функций, которые реализуют один и тот же метод.

Uncle_Theodore ★★ ()
Ответ на: Re: Скорость вызова функций в C от Uncle_Theodore

Re: Скорость вызова функций в C

> Имеет.

Спасибо.

> Я вообще не очень понимаю, зачем тебе несколько разных функций, которые реализуют один и тот же метод.

Если dens(x,y,z), то в каждой -- своя формула. Если idens(x,y) -- неправильно понял про замедление при вызове функции через переменную.

olegd ★★ ()
Ответ на: Re: Скорость вызова функций в C от Uncle_Theodore

Re: Скорость вызова функций в C

> Имеет. Я вообще не очень понимаю, зачем тебе несколько разных функций, которые реализуют один и тот же метод.

А вы например вкурсе почему плюснутый std::sort быстрее пуре-си qsort-а? :)

По теме: вызов функции через указатель -- дорогая неоптимизируемая операция, если нужна максимальная прозиводительность, и при этом generic programming-а хочется, пишите либо макросами либо на плюсы с темплейтами переходите (что разумнее будет).

fmj ()
Ответ на: Re: Скорость вызова функций в C от anonymous

Re: Скорость вызова функций в C

> Было бы неплохо сразу, при запуске, составить таблицу решений, а потом брать значения из неё, а не вычислять каждый раз новое значение в цикле.

В смысле? Для каждой комбинации x,y,z dens(x,y,z) вычисляется всего один раз, если я ничего не напутал. Всего точек x,y -- от 250 000 до 5 000 000. Заранее всё вычислить?

Или что имеется в виду под таблицей решений?

olegd ★★ ()
Ответ на: Re: Скорость вызова функций в C от fmj

Re: Скорость вызова функций в C

> вызов функции через указатель -- дорогая неоптимизируемая операция,

Насколько дорогая?

> пишите либо макросами

Которые препроцессор потом развернёт в несколько однотипных функций, как сейчас?

> либо на плюсы с темплейтами переходите (что разумнее будет).

Можно ссылку на пример?

Спасибо.

olegd ★★ ()
Ответ на: Re: Скорость вызова функций в C от olegd

Re: Скорость вызова функций в C

>> вызов функции через указатель -- дорогая неоптимизируемая операция,

> Насколько дорогая?

Лучше тебе проверить это. Вообще-то на современных процессорах вызов по указателю уже не является дорогой операцией, но, конечно, он дороже inline-варианта.

tailgunner ★★★★★ ()
Ответ на: Re: Скорость вызова функций в C от olegd

Re: Скорость вызова функций в C

> Насколько дорогая?

AFAIK остановка/сброс конвейра част происходят, на таких вызовах, а это жутко дорого.

> Которые препроцессор потом развернёт в несколько однотипных функций, как сейчас?

Так це же компилятор, для достижения максимальной производительности,
мелкие функции всегда инлайнятся. 

> Можно ссылку на пример?


template<double FN(double)> 
double doSOmething(double x, double y)
{
       return x*y + FN(x*y);
}

res = doSomething<RealFunc>(1,2);


fmj ()
Ответ на: Re: Скорость вызова функций в C от fmj

Re: Скорость вызова функций в C

>> Насколько дорогая?

> AFAIK остановка/сброс конвейра част происходят, на таких вызовах

При неправильно предсказанном переходе.

> а это жутко дорого.

На процессоре с жутко длинным конвейером (P4).

В общем, нужно мерять.

tailgunner ★★★★★ ()
Ответ на: Re: Скорость вызова функций в C от fmj

Re: Скорость вызова функций в C

> AFAIK остановка/сброс конвейра част происходят, на таких вызовах, а это жутко дорого.

Хотя может тут я и гоню, но в целом -- inline делает свое дело, посмотрите например:

http://www.tilander.org/aurora/2007/12/comparing-stdsort-and-qsort.html

fmj ()
Ответ на: Re: Скорость вызова функций в C от fmj

Re: Скорость вызова функций в C

>да какая собств. разница, вот версия для Ъ: http://theory.stanford.edu/~amitp/rants/c++-vs-c/

Я думаю ключевым моментом там является это:

Andrew Robb, using a different system, was unable to reproduce the results; on his system, qsort was faster than std::sort. He also has a merge sort routine that only works with arrays (not STL vector and deque), but sorts faster than std::sort. This also shows that if you work hard, you can get something faster than STL.

Так что все эти тесты ничего не говорят.

koTuk ()
Ответ на: Re: Скорость вызова функций в C от koTuk

Re: Скорость вызова функций в C

> Аргументы закончились и начались обычные наезды ?

Блин, баклан, ну сравни сам std::sort хоть тупо, для обычного int массива, и qsort.

#include <stdlib.h>
#include <time.h>
#include <algorithm>

enum { NR = 10000000 };
int arrA[NR];
int arrB[NR];

int cmpC(const void *a, const void *b)
{
        return *(int*)a - *(int*)b;
}

int main()
{
        for (int i=0; i<NR; i++)
        {
                arrA[i] = arrB[i] = rand();
        }


        time_t t1 = time(NULL);

        qsort(arrA, NR, sizeof(int), cmpC);

        time_t t2 = time(NULL);

        std::sort(&arrB[0], &arrB[NR]);

        time_t t3 = time(NULL);

        printf("pure C qsort:\t%d\nC++ std::sort:\t%d\n", t2-t1, t3-t2);
}

$ g++ -Os  1.cpp -o 1 && ./1 

pure C qsort:	4
C++ std::sort:	1


$ g++ --version 
i686-apple-darwin9-g++-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5483)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ uname -a
Darwin mac46.local 9.2.0 Darwin Kernel Version 9.2.0: Tue Feb  5 16:13:22 PST 2008; root:xnu-1228.3.13~1/RELEASE_I386 i386


fmj ()
Ответ на: Re: Скорость вызова функций в C от fmj

Re: Скорость вызова функций в C

> pure C qsort: 4

> C++ std::sort: 1

Похоже, топикстартеру вполне можно использовать указатель, если у него функции будут посложнее одного вычитания целых чисел :)

tailgunner ★★★★★ ()
Ответ на: Re: Скорость вызова функций в C от olegd

Re: Скорость вызова функций в C

Все кто советует заранее вычислять таблицу решений плохо понимают что если нужна высокая точность а следовательно и большая таблица то этот вариант КРАЙНЕ неадекватен потому что одно значение в таблице 4 или 8 байтов, а далее помножаем на размер таблицы и ... сколько у вас эти таблички места займут? Сейчас у вас 5миллионов а завтра нужно будет 500 миллионов и? По опыту скажу так - если вы уверены что вам НЕ прижмет повышать точность (делать больше разбиений) то делайте таблички если нет то лучше не надо ибо как только данные для счетной программы вываливаются из ОЗУ в своп все считайте времени выполнения полный пи..ц оно растет как минимум в 10(для BSD) а то и в 100(Для window) раз, и тут дешевше лишний раз посчитать функцию...

anonymous ()
Ответ на: Re: Скорость вызова функций в C от fmj

Re: Скорость вызова функций в C

bash-3.2$ cat ./1.cpp
#include <stdlib.h>
#include <time.h>
#include <algorithm>

enum { NR = 100000000 };
int arrA[NR];
int arrB[NR];

int cmpC(const void *a, const void *b)
{
        return *(int*)a - *(int*)b;
}

int main()
{
        for (int i=0; i<NR; i++)
        {
                arrA[i] = arrB[i] = rand();
        }


        time_t t1 = time(NULL);

        qsort(arrA, NR, sizeof(int), cmpC);

        time_t t2 = time(NULL);

        std::sort(&arrB[0], &arrB[NR]);

        time_t t3 = time(NULL);

        printf("pure C qsort:\t%d\nC++ std::sort:\t%d\n", t2-t1, t3-t2);
}

bash-3.2$ g++ 1.cpp -o 1 && ./1 
pure C qsort:   51
C++ std::sort:  62

bash-3.2$ g++ -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.2.4/configure --prefix=/usr --libexecdir=/usr/lib --enable-languages=c,c++,objc --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-shared --disable-nls --with-x=no
Thread model: posix
gcc version 4.2.4 (CRUX)

bash-3.2$ uname -a
Linux dell 2.6.25.4-MY #1 SMP PREEMPT Wed May 28 12:17:18 UTC 2008 i686 Genuine Intel(R) CPU T2300 @ 1.66GHz GenuineIntel GNU/Linux


koTuk ()
Ответ на: Re: Скорость вызова функций в C от koTuk

Re: Скорость вызова функций в C

> bash-3.2$ g++ 1.cpp -o 1 && ./1

Ты оптимизацию случайно не включил или намеренно? Ее отсуствие все бы объяснило - Си-вариант оптимизации не поддается, а Си++ - очень даже.

tailgunner ★★★★★ ()
Ответ на: Re: Скорость вызова функций в C от tailgunner

Re: Скорость вызова функций в C

> Ты оптимизацию случайно не включил или намеренно? Ее отсуствие все бы объяснило - Си-вариант оптимизации не поддается, а Си++ - очень даже.

Я думаю он это намеренно, видно же, что это тролль

fmj ()
Ответ на: Re: Скорость вызова функций в C от fmj

Re: Скорость вызова функций в C

ыы...

результаты с linux машины, с 1-в-1 таким-же Core 2 Duo что и у мака:

pure C qsort: 46

C++ std::sort: 17

$ g++ --version

g++ (GCC) 4.1.2 20061115 (prerelease) (SUSE Linux) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$uname -a

Linux testhost 2.6.18.2-34-default #1 SMP Mon Nov 27 11:46:27 UTC 2006 i686 i686 i386 GNU/Linux

Там зузя 10.2 старая. Что не так, почему сортировка в 10 раз медленее чем на маке работает ? Неужто особенности VM Linux-ового, по сравнению с Mach-овским, такую разницу дают?

fmj ()
Ответ на: Re: Скорость вызова функций в C от fmj

Re: Скорость вызова функций в C

>Что не так, почему сортировка в 10 раз медленее чем на маке работает ? Неужто особенности VM Linux-ового, по сравнению с Mach-овским, такую разницу дают?

Если ты из моего поста взял - там нолик добавлен NR = 100000000.

koTuk ()
Ответ на: Re: Скорость вызова функций в C от fmj

Re: Скорость вызова функций в C

>Andrew Robb, using a different system, was unable to reproduce the results

Похоже он на sparc-е тестил :) Вообще троллить я не собирался - мне казалось что многочисленные вызовы не так сильно скажутся на производительности.

koTuk ()

Re: Скорость вызова функций в C

Преждевременная оптимизация - корень всех бед. Реализуй самым простым и понятным способом, потом, если скорости будет не хватать, бери профайлер и им ищи и устраняй узкие места.

anonymous ()
Ответ на: Re: Скорость вызова функций в C от anonymous

Re: Скорость вызова функций в C

> Реализуй самым простым и понятным способом,

Для меня самый понятный и читаемый способ -- через указатели.

olegd ★★ ()
Ответ на: Re: Скорость вызова функций в C от tailgunner

Re: Скорость вызова функций в C

> Похоже, топикстартеру вполне можно использовать указатель, если у него функции будут посложнее одного вычитания целых чисел :)

10-20 арифметических действий, экспонента, арктангенс.

olegd ★★ ()
Ответ на: Re: Скорость вызова функций в C от tailgunner

Re: Скорость вызова функций в C

>> а это жутко дорого.

> На процессоре с жутко длинным конвейером (P4).

Как насчёт Celeron D? На другой машине Athlon.

> В общем, нужно мерять.

5 000 000 точек, с инлайновой подинтегральной функцией 15 секунд, с вызовом по указателю 17. Жить можно. Процессор -- Athlon 64 в 32-битном режиме. На Celeronах будет сильно отличаться?

olegd ★★ ()
Ответ на: Re: Скорость вызова функций в C от fmj

Re: Скорость вызова функций в C

> Так це же компилятор,

Не считаю недостатком, просто спросил как оно работает.

>> Можно ссылку на пример?

>template<double FN(double)>

Спасибо.

olegd ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.