Hello Marc,

Marc Hofmann wrote:
Carsten Neumann <[email protected]> schrieb am 21.05.2009 04:50:47:
 > What compiler are you using, is this with an optimized OpenSG library (I
 > hear debug versions of the MS c++ std library have not so impressive
 > performance characteristics...)?

I’m using Visual C++ 2005 SP1 and an optimized OpenSG version (I tried a downloaded and a self compiled version).

sorry I took me so long to get back to you about this. I've tried this (on linux though) with some models I had at hand, but I can only see large sync times for large changelitsts (see attached SyncTimes.txt). I've used only a minimally modified version of your program (added timing and some printouts) to obtain these (see attached testSyncTime.cpp) with an optimized build of OpenSG.

One thing I've been wondering about is if the fact that syncNeeded is written by one thread and read by another may cause problems. If you replace it with an unsigned int and use something like _InterlockedExchangeAdd(syncNeeded, 1) to signal the need for a sync,
_InterlockedExchangeAdd(syncNeeded, 0) to test the value, and
_InterlockedExchangeAdd(syncNeeded, -1) to set it back you could avoid that.
In your initial mail you were also saying that your models have large textures, so uploading those may also cause drops in the framerate when adding geometry to a scene. Your code unfortunately did not contain the timing parts, is it possible that you were timing more than just the sync, e.g. did you include the time spend in barriers, or the texture upload time? Could you run the attached program with your models please and post the output? I'd like to be able to compare data points from a single program to avoid doubt what exactly is included in my and your timings.

        Cheers,
                Carsten

Create thread sync complete
Loading [/store/home/carsten/devel/models/stl/humanoid_tri.stl] - (0 / 9)
renderThread sync: sizeChanged: 49 / sizeAddRefd: 14 / sizeSubRefd: 1 / 
sizeCreated: 12 / sizeDestroyed: 0
tSyncStart [1.24335e+09] tSyncEnd [1.24335e+09] -- 0.000141144
tStart [1243354374453] tEnd [1243354374453] -- 0 == 0 ms
Time: 1.00012 Frames: 3352 Fps: 3351.6 Sync: 1
Loading [/research/projects/OpenSGNav/models/Cathedral_LowRes.osb] - (1 / 9)
Time: 1.00021 Frames: 3394 Fps: 3393.29 Sync: 0
renderThread sync: sizeChanged: 237258 / sizeAddRefd: 48913 / sizeSubRefd: 
11747 / sizeCreated: 32564 / sizeDestroyed: 0
tSyncStart [1.24335e+09] tSyncEnd [1.24335e+09] -- 0.192347
tStart [1243354377300] tEnd [1243354377492] -- 192 == 0.192 ms
Time: 1.38542 Frames: 3138 Fps: 2265.01 Sync: 1
Loading [/store/home/carsten/devel/models/misc/tie/tie.wrl] - (2 / 9)
renderThread sync: sizeChanged: 524 / sizeAddRefd: 268 / sizeSubRefd: 113 / 
sizeCreated: 265 / sizeDestroyed: 148
tSyncStart [1.24335e+09] tSyncEnd [1.24335e+09] -- 0.000491142
tStart [1243354378542] tEnd [1243354378543] -- 1 == 0.001 ms
Time: 1.01042 Frames: 70 Fps: 69.2779 Sync: 1
Loading [/store/home/carsten/devel/models/stl/humanoid_tri.stl] - (3 / 9)
renderThread sync: sizeChanged: 48 / sizeAddRefd: 14 / sizeSubRefd: 1 / 
sizeCreated: 12 / sizeDestroyed: 0
tSyncStart [1.24335e+09] tSyncEnd [1.24335e+09] -- 0.000104904
tStart [1243354379555] tEnd [1243354379555] -- 0 == 0 ms
Time: 1.01133 Frames: 70 Fps: 69.2156 Sync: 1
Loading [/store/home/carsten/devel/models/misc/tie/tie.wrl] - (4 / 9)
renderThread sync: sizeChanged: 524 / sizeAddRefd: 268 / sizeSubRefd: 113 / 
sizeCreated: 265 / sizeDestroyed: 148
tSyncStart [1.24335e+09] tSyncEnd [1.24335e+09] -- 0.000454903
tStart [1243354380611] tEnd [1243354380612] -- 1 == 0.001 ms
Time: 1.00158 Frames: 69 Fps: 68.8914 Sync: 1
Loading [/research/projects/OpenSGNav/models/I49.3ds] - (5 / 9)
renderThread sync: sizeChanged: 5714 / sizeAddRefd: 1396 / sizeSubRefd: 123 / 
sizeCreated: 1149 / sizeDestroyed: 0
tSyncStart [1.24335e+09] tSyncEnd [1.24335e+09] -- 0.00640512
tStart [1243354381735] tEnd [1243354381741] -- 6 == 0.006 ms
Time: 1.00643 Frames: 68 Fps: 67.5655 Sync: 1
Loading [/store/home/carsten/devel/models/stl/humanoid_tri.stl] - (6 / 9)
renderThread sync: sizeChanged: 48 / sizeAddRefd: 14 / sizeSubRefd: 1 / 
sizeCreated: 12 / sizeDestroyed: 0
tSyncStart [1.24335e+09] tSyncEnd [1.24335e+09] -- 8.98838e-05
tStart [1243354382756] tEnd [1243354382757] -- 1 == 0.001 ms
Time: 1.0089 Frames: 68 Fps: 67.4003 Sync: 1
Loading [/store/home/carsten/devel/models/misc/tie/tie.wrl] - (7 / 9)
renderThread sync: sizeChanged: 524 / sizeAddRefd: 268 / sizeSubRefd: 113 / 
sizeCreated: 265 / sizeDestroyed: 148
tSyncStart [1.24335e+09] tSyncEnd [1.24335e+09] -- 0.000465155
tStart [1243354383813] tEnd [1243354383813] -- 0 == 0 ms
Time: 1.01219 Frames: 68 Fps: 67.1813 Sync: 1
Loading [/research/projects/OpenSGNav/models/OilRig_02.osb] - (8 / 9)
Time: 1.00147 Frames: 67 Fps: 66.9015 Sync: 0
Time: 1.00245 Frames: 66 Fps: 65.839 Sync: 0
Time: 1.01407 Frames: 67 Fps: 66.0706 Sync: 0
FATAL:  Compressed stream has wrong checksum.
Time: 1.00678 Frames: 63 Fps: 62.5758 Sync: 0
renderThread sync: sizeChanged: 100044 / sizeAddRefd: 26754 / sizeSubRefd: 6650 
/ sizeCreated: 16502 / sizeDestroyed: 1977
tSyncStart [1.24335e+09] tSyncEnd [1.24335e+09] -- 0.175663
tStart [1243354388481] tEnd [1243354388657] -- 176 == 0.176 ms
Time: 1.01516 Frames: 42 Fps: 41.3726 Sync: 1
Time: 1.00249 Frames: 51 Fps: 50.8733 Sync: 0
Time: 1.00968 Frames: 51 Fps: 50.511 Sync: 0
Time: 1.00992 Frames: 51 Fps: 50.4992 Sync: 0
Time: 1.01149 Frames: 51 Fps: 50.4206 Sync: 0
Time: 1.01568 Frames: 51 Fps: 50.2128 Sync: 0
#include <OSGSimpleSceneManager.h>
#include <OSGSceneFileHandler.h>
#include <OSGSimpleTexturedMaterial.h>
#include <OSGGLUTWindow.h>
#include <OSGGLUT.h>

OSG_USING_NAMESPACE

SimpleSceneManager *mgr;
NodePtr scene;
Thread* renderThread;
Thread* creationThread;
Barrier* syncBarrier;
bool syncNeeded;

int setupGLUT( int *argc, char *argv[] );

NodePtr createScenegraph()
{
    NodePtr n = Node::create();
    beginEditCP(n);
    n->setCore(Group::create());
    endEditCP(n);

    return n;
}


// executed by each geometry creation thread
void create(void *args)
{
    osg::FieldContainerPtr pProto = osg::Geometry::getClassType().getPrototype();
    osg::GeometryPtr pGeoProto = osg::GeometryPtr::dcast(pProto);

    if(pGeoProto != NullFC)
    {
        pGeoProto->setIgnoreGLForAspect(osg::Thread::getAspect());
    }

    pProto = osg::TextureChunk::getClassType().getPrototype();
    osg::TextureChunkPtr pTexChunkProto = osg::TextureChunkPtr::dcast(pProto);

    if(pTexChunkProto != NullFC)
    {
        pTexChunkProto->setIgnoreGLForAspect(osg::Thread::getAspect());
    }

    syncBarrier->enter(2);
    std::cout << "Create thread sync " << std::flush;
    renderThread->getChangeList()->apply();
    std::cout << "complete\n" << std::flush;
    syncBarrier->enter(2);

    std::vector<std::string> file_list;
    std::ifstream file;
    file.open("file.lst");
    while (!file.eof())
    {
        std::string line;
        std::getline(file, line);
        file_list.push_back(line);
    }

    unsigned int file_index = 0;

    while (true)
    {
        NodePtr groupNode = scene;

        if (file_index == file_list.size())
            break;

        // (1)
        // I have a std::vector with filenames and load with
        // OpenSG loader 1 file in each loop
        std::string file_name = file_list[file_index];

        std::cout << "Loading [" << file_name << "] - (" << file_index << " / " << file_list.size() << ")\n" << std::flush;

        NodePtr new_node = SceneFileHandler::the().read(file_name.c_str());

        if(new_node != NullFC)
        {
            beginEditCP(groupNode);
            groupNode->addChild(new_node);
            endEditCP(groupNode);

            // ready to sync
            syncNeeded = true;

            // wait for the render thread to sync over changes
            syncBarrier->enter(2);
            syncNeeded = false;
            syncBarrier->enter(2);
        }
        else
        {
            std::cout << "Warning: Loading of file [" << file_name << "] failed.\n" << std::flush;
        }

        osgsleep(1000);

        file_index++;
    }
}


int main(int argc, char *argv[])
{
#if OSG_MINOR_VERSION > 2
    ChangeList::setReadWriteDefault();
#endif
    osgInit(argc, argv);

    int winid = setupGLUT(&argc, argv);
    GLUTWindowPtr gwin = GLUTWindow::create();

    beginEditCP(gwin);
    gwin->setId(winid);
    endEditCP(gwin);

    gwin->init();

    scene = createScenegraph();

    mgr = new SimpleSceneManager;
    mgr->setWindow(gwin );
    mgr->setRoot (scene);
    mgr->setStatistics(true);
    mgr->showAll();

    syncBarrier = Barrier::get("syncBarrier1");
    renderThread = dynamic_cast<Thread *>(ThreadManager::getAppThread());
    syncNeeded = false;

    // start the threads
    creationThread = dynamic_cast<Thread *>(ThreadManager::the()->getThread("creationThread"));
    creationThread->runFunction(create, 1, NULL);
       
    // wait for the creation threads to sync over changes
    syncBarrier->enter(2);
    syncBarrier->enter(2);

    // clear changes - they are synced to aspect 1 now
    Thread::getCurrentChangeList()->clearAll();

    beginEditCP(mgr->getCamera());
    mgr->getCamera()->setNear( 0.5 );
    mgr->getCamera()->setFar( 15000 );
    endEditCP(mgr->getCamera());

    glutMainLoop();

    return 0;
}

void display(void)
{
    static bool   frameSync   = false;

    static UInt32 frameCount  = 0;
    static Time   tFrameStart = getSystemTime();
    static Time   tFrameStop  = getSystemTime();

    // check thread for available changes
    if(syncNeeded == true)
    {
        // (2)
        syncBarrier->enter(2);
        std::cout << "renderThread sync:"
                  << " sizeChanged: " << creationThread->getChangeList()->sizeChanged()
                  << " / sizeAddRefd: " << creationThread->getChangeList()->sizeAddRefd()
                  << " / sizeSubRefd: " << creationThread->getChangeList()->sizeSubRefd()
                  << " / sizeCreated: " << creationThread->getChangeList()->sizeCreated()
                  << " / sizeDestroyed: " << creationThread->getChangeList()->sizeDestroyed()
                  << "\n" << std::flush;

        Time      tSyncStart = getSystemTime();
        TimeStamp tStart     = getTimeStamp ();
        creationThread->getChangeList()->applyAndClear();
        TimeStamp tEnd       = getTimeStamp ();
        Time      tSyncEnd   = getSystemTime();

        std::cout << "tSyncStart [" << tSyncStart << "] tSyncEnd [" << tSyncEnd << "] -- " << (tSyncEnd - tSyncStart) << "\n" << std::flush;
        std::cout << "tStart [" << tStart << "] tEnd [" << tEnd << "] -- "
                  << (tEnd - tStart) << " == " << getTimeStampMsecs(tEnd - tStart) << " ms\n" << std::flush;
        syncBarrier->enter(2);

        frameSync = true;
    }

    mgr->showAll();

//    Pnt3f bbMin;
//    Pnt3f bbMax;

//    scene->updateVolume();
//    scene->getVolume().getBounds(bbMin, bbMax);

//    std::cout << "bbMin [" << bbMin << "] bbMax [" << bbMax << "]\n" << std::flush;

    mgr->redraw();
    renderThread->getChangeList()->clearAll();

    ++frameCount;

    tFrameStop = getSystemTime();

    if((tFrameStop - tFrameStart) > 1.f)
    {
        std::cout << "Time: " << (tFrameStop - tFrameStart)
                  << " Frames: " << frameCount
                  << " Fps: " << (frameCount / (tFrameStop - tFrameStart))
                  << " Sync: " << frameSync << "\n" << std::flush;

        tFrameStart = tFrameStop;
        frameCount  = 0;
        frameSync   = false;
    }
}


void reshape(int w, int h)
{
    mgr->resize(w, h);
    glutPostRedisplay();
}

void mouse(int button, int state, int x, int y)
{
    if (state)
        mgr->mouseButtonRelease(button, x, y);
    else
        mgr->mouseButtonPress(button, x, y);

    glutPostRedisplay();
}

void motion(int x, int y)
{
    mgr->mouseMove(x, y);
    glutPostRedisplay();
}

int setupGLUT(int *argc, char *argv[])
{
    glutInit(argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);

    int winid = glutCreateWindow("OpenSG Multithreading Test");

    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutReshapeFunc(reshape);
    glutIdleFunc(display);

    return winid;
}
------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT 
is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & 
iPhoneDevCamp as they present alongside digital heavyweights like Barbarian 
Group, R/GA, & Big Spaceship. http://p.sf.net/sfu/creativitycat-com 
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to