Re: [osg-users] osg::DeleteHander - the good, the bad and ugly

2007-09-01 Thread Cedric Pinson
I tried a little brut test about smart pointer from osg and the similar 
approch in boost with instrusive_ptr

here the result with the source code:

PROFILE_ROOT prt 100.00 glb 100.00 - time  31.785504 avg  31.785504 
ncall 1 
osg_smprt   2.85 glb   2.85 - time   0.905553 avg   0.905553 
ncall 1 
boost_sm prt   2.84 glb   2.84 - time   0.901856 avg   0.901856 
ncall 1 
boost2  prt  23.95 glb  23.95 - time   7.611869 avg   7.611869 
ncall 1 
osg2 prt  70.37 glb  70.37 - time  22.366193 avg  22.366193 
ncall 1 


Cedric

Robert Osfield wrote:

Hi André,

On 8/31/07, André Garneau [EMAIL PROTECTED] wrote:
  

FYI you might want to check the Boost::intrusive_ptr implementation (similar
in concept to OSG's ref_ptr) as it is using an underlying implementation
that does atomic reference counting (using CPU native Interlocked
test/increments). Note that I'm not suggesting to use Boost, just to get
ideas from this implementation.



Thanks for the suggestion.

I'm chasing bugs right now.  Could members of the community have a
look into this? i.e. the possibility of adding atmoic counts into
OpenThreads and ref_ptr.

Cheers,
Robert.
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
  
/*
#
# Copyright (C) 2007 Cedric Pinson
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Authors:
#  Cedric Pinson [EMAIL PROTECTED]
#
# 
*/
#ifdef HAVE_CONFIG_H
#include ../config.h
#endif
#include iostream

#ifdef USE_NPROFILE
#include nprofile/profile.h
#endif

#include cstdlib
#include osg/Referenced
#include osg/ref_ptr

#include cmath

#include boost/config.hpp
#include boost/shared_ptr.hpp
#include boost/intrusive_ptr.hpp



struct Test : public osg::Referenced
{
protected:
public:
  int value;
  Test(): value(1) {}
  void test1() { value+=1;}
  void test2()  { value+=2;}
};

struct TestBoost
{
  unsigned int count;

  TestBoost(): count(0)
  {
value = 1;
  }

  int value;
  void test1() { value+= 1;}
  void test2()  { value+=2;}

};

void intrusive_ptr_add_ref(TestBoost * p)
{
  ++p-count;
}

void intrusive_ptr_release(TestBoost * p)
{
  if(--p-count == 0) delete p;
}



static boost::intrusive_ptrTestBoost test_boost= new TestBoost;
static osg::ref_ptrTest test_osg = new Test;

void testboost(int n)
{
  NPROFILE_SAMPLE(boost_sm);
  for (int i = 0;i  n; i++) {
  for (int j = 0;j  n; j++) {
test_boost-test1();
test_boost-test2();
test_boost-test1();
test_boost-test2();
test_boost-test1();
test_boost-test2();
  }
  }
}

void testboost2(int n)
{
  NPROFILE_SAMPLE(boost2);
  for (int i = 0;i  n; i++) {
boost::intrusive_ptrTestBoost test_boost2;
boost::intrusive_ptrTestBoost test_boost3;
test_boost2 = test_boost;
test_boost3 = test_boost2;
test_boost = test_boost3;
  }
}

void testosg(int n)
{
  NPROFILE_SAMPLE(osg_sm);
  for (int i = 0;i  n; i++) {
  for (int j = 0;j  n; j++) {
test_osg-test1();
test_osg-test2();
test_osg-test1();
test_osg-test2();
test_osg-test1();
test_osg-test2();
  }
  }
}

void testosg2(int n)
{
  NPROFILE_SAMPLE(osg2);
  for (int i = 0;i  n; i++) {
osg::ref_ptrTest test_osg2;
osg::ref_ptrTest test_osg3;
test_osg2 = test_osg;
test_osg3 = test_osg2;
test_osg = test_osg3;
  }
}

void func(int arg)
{
  //  NPROFILE_SAMPLE(root);
  testosg(arg);
  testboost(arg);
  testboost2(arg);
  testosg2(arg);
}

int main(int argc , char **argv)
{

  unsigned int arg = 2147483647;
  std::cout  arg  std::endl;

  nprf::GetProfiler()-Reset();

  func(arg);

  nprf::GetProfiler()-EndProfile();
  nprf::GetProfiler()-GetRootNode()-DisplayFlatStats(std::cout);
  std::cout  test_osg-value  std::endl;
  std::cout  test_boost-value  std::endl;

  return 0;
}
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


[osg-users] osg::DeleteHander - the good, the bad and ugly

2007-08-31 Thread Robert Osfield
Hi All,

With the introduction of the new DrawThreadPerContext and
CullThreadPerCameraDrawThreadPerContext threading models came the use
the osg::DeleteHandler, its not used in the other threading models as
it isn't required.  The DeleteHandler roles is to cache objects that
were being deleted for a couple of frames to allow the rendering
backend to dispatch all the data from StateSet and Drawables into the
OpenGL FIFO without these objects being deleted from under them.

Normally the scene graph uses ref_ptr everywhere to stop objects
from being deleted whilst still being used, and this is really
successfully and very reliable, has been for many years.   But.. its
only reliable if you use it, and the rendering back end of the OSG has
used C pointers rather than ref_ptr so it hasn't had this safety
net.  The reason for not using ref_ptr is purely performance
considerations - when you might be display 10's of thousands of
Drawables per frame and near 100 frames per second you could easily be
doing a million ref/unref per second so it is expensive - how
expnsive?  I tested this afternoon and saw a 6% frame rate hit on CPU
limited scenes with adding using of ref_ptr into the rendering
backend.

Now DeleteHandler provides the safety net required to allow use to
keep using C pointers in the rendering backend, and avoids the 6%
performance penalty, which means the DrawThreadPerContext and
CullThreadPerCameraDrawThredPerContext maximize the gain over only
SingleThreaded and CullDrawThreadPerContext.

So that's the good, slightly better performance. The bad is obviously
the extra complexity involved in Referenced and osgViewer required to
manage the DeleteHandler.  Since this is all written and working and
largely hidden from general users this its not such a bad thing.

But the ugly... clean up of the application does get more awkward as
the DeleteHandler defers deletion until a DeleteHandler::flush() is
called, and also this caching mechansim needs to be turned off.  Now
I've added code into osgViewer to automatically do this for you, and
this works to an extent... but its turned out that it's not a robust
solution, with users coming across problems with crashes on exit - I
believe due to how the DeleteHandler change the order of destruction.

Potentially I could write a cleanUpOSG() function that you call on
exit, or perhaps even come up with some clever C++ way of
destructing things, but its all more complexity to push back on to
users, and something almost certainly that is going to cause problems
with it not used correctly or not all, or called when it shouldn't be
etc.

I've come to a point now that I've decided with DeleteHandler I was
possible being too clever, and in the greater schemes of things its
complicated not just in coding, but in scene graph debugging and
usage.  Pushing it further is really just put a plaster a broken
concept.

So in svn I have checked in the use of ref_ptrStateSet in
include/osgUtil/StateGraph, and ref_ptrDrawable in
include/osgUtil/RenderLeaf.  I have also disable the use of
DeleteHandler.  The new code and old code still sit alonside each
other and #define toggles between the two.  The default is to use
ref_ptr and not to use DeleteHandler.

What might the effect be on you?  For most it'll probably be a
negligible hit in performance as you probably aren't CPU (in cull)
limited, for those that are then you might see a ~6% fps hit.  The
upside and the motivation for this change is that crash on exit
problems related to DeleteHandler should now be gone.

This change isn't the end of road for this issue - I'd like to find a
way to avoid  or at least minimize the performance penalty associated
with the use of ref_ptr in the rendering backend.  Is it time to
revisit atomic reference counting?  Is there another scheme we can
introduce in place of ref_ptr for the rendering backend?

From the community I would like feedback, especially those who've seen
crash on exit - do a svn update and let me know if the crashes are
gone.  Also those with expertise on atmoic ref counting please step
forward :-)

Cheers,
Robert.
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] osg::DeleteHander - the good, the bad and ugly

2007-08-31 Thread Robert Osfield
Hi André,

On 8/31/07, André Garneau [EMAIL PROTECTED] wrote:
 FYI you might want to check the Boost::intrusive_ptr implementation (similar
 in concept to OSG's ref_ptr) as it is using an underlying implementation
 that does atomic reference counting (using CPU native Interlocked
 test/increments). Note that I'm not suggesting to use Boost, just to get
 ideas from this implementation.

Thanks for the suggestion.

I'm chasing bugs right now.  Could members of the community have a
look into this? i.e. the possibility of adding atmoic counts into
OpenThreads and ref_ptr.

Cheers,
Robert.
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org