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

Reply via email to