I have to admit my experience backs up Michael claims. Checked Iterators (in release) can have a significant impact on performance depending on how you use iterators. Most STL calls have been optimized by MS to have almost a 0% overhead with checked iterators enabled. Code directly using iterators (such as Boost or OSG for example) will be significantly slower. 10x slower does not surprise me, although I've noticed 0.1x to 3x slower to be more common.
Checked Iterators enabled by default is a bad decision from MSVC STL team. Most C++ developers have been complaining quite loudly about it on MS forums and blogs for ages, only to be met by the same answer everytime: "It's for security. Security is good for you, you should have checked iterators enabled all the time" (aka "Microsoft knows what's good for you better than you do"). For the same reasons Robert explained, I'm not in favour of changing OSG code to make it faster with checked iterators. But I can definitely understand why one would want to disable checked iterators. Tanguy -----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of Jean-Sébastien Guay Sent: Friday 01 May 2009 14:29 To: OpenSceneGraph Users Subject: Re: [osg-users] Visual Studio, Iterator Debugging, Secure SCL, Slow Performance, and getFileExtension "bug" Hello Michael, > I've recently encountered this same problem myself. My experiments show > that iterating over a vector with an iterator is ***TEN TIMES SLOWER*** > than with iterator debugging disabled. In release builds! I'm somewhat skeptical of this claim. What experiments were they, and are you sure they're representative of an actual application? Sure, we all know that iterator debugging (_HAS_ITERATOR_DEBUGGING) and checking (_SECURE_SCL) takes a lot of time in debug builds, but release builds should be virtually unaffected. Note that _HAS_ITERATOR_DEBUGGING only has an effect in debug builds - it is completely disabled in release - but _SECURE_SCL stays enabled even in release. However, in my testing, it has virtually no effect in release. Think about it - would MS really put default values into their compiler that would make all applications on their platform ten times slower? How would that make their platform look, especially now that most applications can run on multiple platforms? I think you may be focusing on test cases that do not match actual application results, but of course to be sure you'd have to publish your test cases. > Ideally I'd just define _SCL_SECURE to 0, but I can't as I'm dependent > on closed-source libraries without it defined and this has given me > weird crashes. We're on the same boat. We have to make two builds of everything because in some builds we link to Vega Prime which is built with iterator debugging disabled, but in all other cases we want to keep the VS default values so we don't put an additional burden on our customers who want to link to our libraries. It just about doubles the number of builds we need in our build matrix, which is a drag. I personally think that until we can publically and conclusively prove otherwise, changing the VS default values for this is not useful and just puts an additional burden on others trying to link to your libs. See what happens with Vega Prime - because they decided to change the iterator debugging setting, they force us to make twice the number of builds. That's a considerable waste of time and resources for us. A while ago, we tried building all our libraries with iterator debugging and _SECURE_SCL turned off. We thought it would be a good way to reduce our build matrix, but it ended up just moving the burden onto support because customers who wanted to link to our libraries had to remember to disable these in their projects too. Anyways - we switched back to default settings on our OSG-based builds lately, and as I said I haven't seen a significant performance difference in release. That's for actual applications in a real-world setting... I didn't do any real timings at the time, but I think I would have noticed a 10x difference! Especially since OSG is iterator-heavy. Remember - you're not supposed to do any benchmarking in debug (it's not representative of real performance, on any platform) and release builds *should* be relatively unaffected (unless you can prove otherwise). > However, I've discovered that using std::for_each in place of a for loop > provides a massive speed up - it performs the same is if iterator > debugging were disabled. I'm skeptical about this too... Here's the source for std::for_each (MSVC's implementation): // TEMPLATE FUNCTION for_each template<class _InIt, class _Fn1> inline _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func) { // perform function for each element _DEBUG_RANGE(_First, _Last); _DEBUG_POINTER(_Func); _CHECKED_BASE_TYPE(_InIt) _ChkFirst(_CHECKED_BASE(_First)); _CHECKED_BASE_TYPE(_InIt) _ChkLast(_CHECKED_BASE(_Last)); for (; _ChkFirst != _ChkLast; ++_ChkFirst) _Func(*_ChkFirst); return (_Func); } Apart from the 2 _DEBUG and 2 _CHECKED macros, this does not do anything different than I would do manually. It could be rewritten: void for_each(iterator first, iterator last, function_ptr function) { for (; first!= last; ++first) function(*first); } Now, out of the 4 macros, the first two are enabled if iterator debugging is enabled (_HAS_ITERATOR_DEBUGGING), and the other two are enabled if _SECURE_SCL is enabled. Now, the savings you see might come from the fact that the iterators are checked only once and then unchecked iterators are used for the loop itself. That would actually make sense. But I haven't seen any significant performance difference between the two myself, so I'm skeptical. I agree with Robert, changing all loops to std::for_each wholesale would be likely to introduce bugs, since you need to code up a functor for each loop. In addition to introducing more code, that moves the inner loop logic out of the scope where it's used, which makes it harder to follow. If we could use boost::foreach instead - and if we could prove that it has the same benefits that you say std::for_each has - then that might be a good alternative, because it allows a more classic loop structure where the code stays local, no need for functors. But introducing boost as a dependency for OSG is out of the question, as has been stated often by Robert. Anyways, I hope I didn't come out too strongly. I'd be glad if we could find a way to get a massive speed-up, of course, but I'm skeptical about the results you claim to get, that's all. J-S -- ______________________________________________________ Jean-Sebastien Guay [email protected] http://www.cm-labs.com/ http://whitestar02.webhop.org/ _______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org _______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

