c++ - about function pointer: why the overhead time changes when the content of the function changes -


here c++ code, , use vs2013, release mode

#include <ctime> #include <iostream>  void tempfunction(double& a, int n) {     = 0;     (double = 0; < n; ++i)     {     += i;     } }  int main() {     int n = 1000; // 1000 8000      double value = 0;     auto t0 = std::time(0);     (int = 0; < 1000000; ++i)     {         tempfunction(value, n);     }     auto t1 = std::time(0);     auto tempfunction_time = t1-t0;     std::cout << "tempfunction_time = " << tempfunction_time << '\n';      auto tempfunctionptr = &tempfunction;      value = 0;     t0 = std::time(0);     (int = 0; < 1000000; ++i)     {         (*tempfunctionptr)(value, n);     }     t1 = std::time(0);     auto tempfunctionptr_time = t1-t0;     std::cout << "tempfunctionptr_time = " << tempfunctionptr_time << '\n';      std::system("pause"); } 

i change value of n 1000 8000, , record tempfunction_time , tempfunctionptr_time. results weird:

n=1000 , tempfunction_time=1, tempfunctionptr_time=2; n=2000 , tempfunction_time=2, tempfunctionptr_time=6; n=4000 , tempfunction_time=4, tempfunctionptr_time=11; n=8000 , tempfunction_time=8, tempfunctionptr_time=21; 

tempfunctionptr_time - tempfunction_time not constant, , tempfunctionptr_time = 2~3 * tempfunction_time. difference should constant overhead of function pointer.

what wrong?

edit:

assume vs2013 inlines tempfunction if it called tempfunction(), , not inline if called (*tempfunctionptr), can explain difference. so, if true, why can not compiler inline (*tempfunctionptr) ?

i compiled existing code g++ on linux machine, , found time short measured accurately in seconds, rewrote use std::chrono measure time more precisely - had "use" variable value (hence "499500" being printed below), otherwise compiler optimise away first loop. following result:

tempfunction_time = 1.47983 499500 tempfunctionptr_time = 1.69183 499500 

now, results have gcc (version 4.6.3 - other versions available , may give other results!), not same compiler microsoft, results may differ - different compilers optimise code quite differently @ times. i'm quite surprised compiler doesn't figure out result of tempfunction needs calculating once. hey, made easier write benchmark without trickery.

my second observation that, compiler, if replaceint n=1000; loop for(int n=1000; n <= 8000; n *= 2) around main code, there no or little difference between 2 cases - i'm not entirely sure why, because code looks identical (there no call via function-pointer, because compiler knows function pointer constant), , tempfunction gets inlined in both cases. (the same "equality" happens when n other values 1000 - i'm far sure going on here....

to measure difference between function pointer , direct function call, need move tempfunction separate file, , "hide" actual value stored in tempfunctionptr such compiler doesn't figure out doing.

in end, ended this:

typedef void (*funptr)(double &a, int n);  void tempfunction(double& a, int n) {     = 0;     (double = 0; < n; ++i)     {     += i;     } }  funptr getfunptr() {     return &tempfunction; } 

and "main" code this:

#include <iostream> #include <chrono>  typedef void (*funptr)(double &a, int n);  extern void tempfunction(double& a, int n); extern funptr getfunptr();  int main() {     for(int n = 1000; n <= 8000; n *= 2)     {     std::cout << "n=" << n << std::endl;     double value = 0;     auto t0 = std::chrono::system_clock::now();     (int = 0; < 1000000; ++i)     {         tempfunction(value, n);     }     auto t1 = std::chrono::system_clock::now();;     std::chrono::duration<double> tempfunction_time = t1-t0;     std::cout << "tempfunction_time = " << tempfunction_time.count() << '\n';     std::cout << value << std::endl;      auto tempfunctionptr = getfunptr();      value = 0;     t0 = std::chrono::system_clock::now();     (int = 0; < 1000000; ++i)     {         (*tempfunctionptr)(value, n);     }     t1 = std::chrono::system_clock::now();     std::chrono::duration<double> tempfunctionptr_time = t1-t0;     std::cout << "tempfunctionptr_time = " << tempfunctionptr_time.count() << '\n';     std::cout << value << std::endl;     } } 

however, difference thousands of second, , variant clear winner, conclusion obvious one, "calling function slower inlining it".

n=1000 tempfunction_time = 1.78323 499500 tempfunctionptr_time = 1.77822 499500 n=2000 tempfunction_time = 3.54664 1.999e+06 tempfunctionptr_time = 3.54687 1.999e+06 n=4000 tempfunction_time = 7.0854 7.998e+06 tempfunctionptr_time = 7.08706 7.998e+06 n=8000 tempfunction_time = 14.1597 3.1996e+07 tempfunctionptr_time = 14.1577 3.1996e+07 

of course, if "only half hiding trick", function known , inlineable in first case, , not known , through function pointer, can perhaps expect difference. calling function through pointer in not expensive. real difference comes when compiler decides inline function.

obviously, these results of gcc 4.6.3, not same compiler msvs2013. should make "chrono" modifications in above code, , see difference makes.


Comments

Popular posts from this blog

python - Subclassed QStyledItemDelegate ignores Stylesheet -

java - HttpClient 3.1 Connection pooling vs HttpClient 4.3.2 -

SQL: Divide the sum of values in one table with the count of rows in another -