4

I just finished profiling a block of code which took up too much time. The code in question creates a large boost::graph from some std::vectors and a std::set, which are sorted and inserted into very many times. However, I was surprised to see that the majority of the time was not spent in sorting or inserting, but in std::_Iterator_base12::_Orphan_me - 97.27% reported by AMD CodeAnalyst. What is this function? It seems to be called ~2200 times, the total runtime is ~30 seconds.

CodeAnalyst doesn't give me a very good call stack, and seems to cut names after 120 or so characters, which is no match for a boost template type. If there is a way to improve this (I'm quite new to CodeAnalyst), please say so and I might be able to give better information.

carlpett
  • 12,203
  • 5
  • 48
  • 82
  • Are you sure you compiled code in release mode before profiling? A lot of the underlying iterator machinery get's optimized away in release compared to debug mode. – Praetorian Jul 07 '11 at 16:26
  • In performance tuning, surprises are to be expected. Is the program doing I/O? If so, that may be 97% of nothing. Regardless, if you want to see what's really going on, [give this a try](http://stackoverflow.com/questions/375913/what-can-i-use-to-profile-c-code-in-linux/378024#378024). – Mike Dunlavey Jul 07 '11 at 18:48
  • Iterators have been made into a non-normalized bfd, with back pointers to their containers. You can turn off all that. [Check this out.](http://benc45.wordpress.com/2008/07/13/performance-killer-debug-iterator-support-in-visual-studio/) – Mike Dunlavey Jul 07 '11 at 19:42
  • @Mike and @Praetorian: Thanks! No, I had not switched to release mode (*facepalm*). Esp. Mike, the linked blog post was very informative. Would you mind posting it as an answer? (btw, switching to release, runtime on a larger problem decreased from >40 min to less than 2 seconds...) – carlpett Jul 08 '11 at 06:31

1 Answers1

2

The answer is to run the profiler in the Release mode, see performance killer -Debug Iterator Support in Visual studio.

Iterator checking, enabled by _SECURE_SCL, performs minimal checks that serve as a last line of security defense... Because it is enabled by default in release mode, strives to impose minimal performance penalties. Therefore, when it is enabled, although iterators have pointers back to their containers, containers don’t have pointers to their iterators...

The Swap Fix in Orcas makes every Standard container own an additional dynamically allocated object, imaginatively called "the aux object". Each container holds a pointer to its aux object, which holds a pointer back to the container. Each iterator, instead of holding a pointer directly to its parent container, now holds a pointer to its parent container’s aux object...

The performance issue is that the aux object, while unavoidable... is not free. Each Standard container is now larger because it has to hold a pointer to its aux object. The aux object has to be dynamically allocated, occupying more space and taking more time. And _SECURE_SCL has perform a double indirection when going from an iterator to its parent container.

Community
  • 1
  • 1
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • I came across [a question](http://stackoverflow.com/questions/36686979/regex-error-using-msvc-2013/36688163#36688163) that is related: the regex search operation in Debug mode threw a stack overflow exception right at the `Orphan_me()` method. Switching to *Release* solved it (and also making a regex pattern a simpler one could help). – Wiktor Stribiżew Apr 18 '16 at 12:31