Measuring Overhead for Exception Handling in C ++

What is the best way to measure overhead / error handling in C ++?

Please provide separate code samples.

I am targeting Microsoft Visual C ++ 2008 and gcc.

I need to get results from the following cases:

  • Overhead if no try / catch blocks
  • Overhead when try / catch blocks are present, but exceptions are not thrown
  • Excess emission overhead
+14
c ++ performance gcc exception visual-c ++
04 Sep '08 at 6:38
source share
8 answers

Section 5.4 of the draft C ++ Technical Performance Report is entirely devoted to the overhead of exceptions.

+34
Sep 04 '08 at 9:30
source share

As a suggestion: don't worry too much with overhead when exceptions are thrown. Implementation of exception handling is usually not accelerated, but slower caught. This is normal, as these cases are certainly exceptional.

Charles

+9
Sep 04 '08 at 7:32
source share

Here is the measurement code I came up with. Do you see any problems with this?

Works on Linux and Windows are still compiled with:

g++ exception_handling.cpp -o exception_handling [ -O2 ] 

or, for example, Visual C ++ Express .

To get the base case ("exception support completely excluded from the language"), use:

 g++ exception_handling.cpp -o exception_handling [ -O2 ] -fno-exceptions -DNO_EXCEPTIONS 

or similar settings in MSVC.

Some preliminary results are here . They are probably all hokey due to different loading of the machine, but they give some insight into the relative handling of exception handling. (Summary: no or few when no exceptions are thrown, huge when they are actually thrown.)

 #include <stdio.h> // Timer code #if defined(__linux__) #include <sys/time.h> #include <time.h> double time() { timeval tv; gettimeofday(&tv, 0); return 1.0 * tv.tv_sec + 0.000001 * tv.tv_usec; } #elif defined(_WIN32) #include <windows.h> double get_performance_frequency() { unsigned _int64 frequency; QueryPerformanceFrequency((LARGE_INTEGER*) &frequency); // just assume it works return double(frequency); } double performance_frequency = get_performance_frequency(); double time() { unsigned _int64 counter; QueryPerformanceCounter((LARGE_INTEGER*) &counter); return double(counter) / performance_frequency; } #else # error time() not implemented for your platform #endif // How many times to repeat the whole test const int repeats = 10; // How many times to iterate one case const int times = 1000000; // Trick optimizer to not remove code int result = 0; // Case 1. No exception thrown nor handled. void do_something() { ++result; } void case1() { do_something(); } // Case 2. No exception thrown, but handler installed #ifndef NO_EXCEPTIONS void do_something_else() { --result; } void case2() { try { do_something(); } catch (int exception) { do_something_else(); } } // Case 3. Exception thrown and caught void do_something_and_throw() { throw ++result; } void case3() { try { do_something_and_throw(); } catch (int exception) { result = exception; } } #endif // !NO_EXCEPTIONS void (*tests[])() = { case1, #ifndef NO_EXCEPTIONS case2, case3 #endif // !NO_EXCEPTIONS }; int main() { #ifdef NO_EXCEPTIONS printf("case0\n"); #else printf("case1\tcase2\tcase3\n"); #endif for (int repeat = 0; repeat < repeats; ++repeat) { for (int test = 0; test < sizeof(tests)/sizeof(tests[0]); ++test) { double start = time(); for (int i = 0; i < times; ++i) tests[test](); double end = time(); printf("%f\t", (end - start) * 1000000.0 / times); } printf("\n"); } return result; // optimizer is happy - we produce a result } 
+7
04 Sep '08 at 7:38
source share

Kevin Frey talks about the effectiveness of exception handling in his speech, " The Cost of C ++ Exception Handling in Windows ." (In the Summary and Summary section, there is one element of the list that says: "[The cost of handling exceptions is not always measured.")

+3
Sep 05 '08 at 15:55
source share

There is no really good way to measure this in code. You will need to use a profiler.

This will not show you how much time has been spent on handling exceptions, but with a little research you will find out which of the execution methods deal with exceptions (for example, for VC ++. NET it __cxx_exc [...]).

Add your time and you have overhead. In our project, we used vTunes from Intel, which works with both Visual C ++ and gcc.

Edit: Well, if you just need a common number that can work. Thought you had an actual profile app where you can't just turn off exceptions.

+2
Sep 04 '08 at 7:42
source share

One more note about the effectiveness of exception handling: simple tests do not take into account caching. The try code and catch code are so small that everything is in the command and data cache. But compilers can try to move catch code far from the try code, which reduces the amount of code that is usually stored in the cache, thereby improving performance.

If you compare exception handling with traditional C-style return value checking, this caching effect should also be taken into account (the issue is usually ignored in discussions).

Charles

+2
Sep 04 '08 at 14:53
source share

Will the answer depend on what kind of cleaning should happen as a result of the throw? If you throw away excrement, which causes the whole load of objects to go out of scope up the stack, then this will add extra overhead.

In other words, I'm not sure if there is an answer to the third question, which does not depend on the specifics of the code.

0
04 Sep '08 at 20:58
source share

Details on how g ++ handles exceptions are shown here . He describes this as an Itanium architecture, however the common methods used are the same. It will not indicate the exact overhead in terms of time, however you can get information that there will be overhead for the rough code.

0
Feb 17 '09 at 17:32
source share



All Articles