0

I'm developing an application using OpenSceneGraph and I'm encountering some odd behavior in an if statement. I'm not sure if it's specific to the API because it simply makes no sense on any level to me.

The code:

if ( !fileAddList_.empty() )
{
    sg::FileStampThread::instance()->addFiles( fileAddList_ );
    fileAddList_.clear();
}

Where:

  • fileAddList_: a static vector of custom objects used to maintain filenames

  • FileStampThread: an instance of an OpenThreads object

  • addFiles(): a method in the thread which saves the list of file objects passed to it

The above code implements hotloading in my application. The FileStampThread instance runs continuously, checking time stamps of filenames passed to it. Once a stamp changes, the filename is saved to another list and passed back for reloading.

What's odd is that the update traversal of the scene graph (when this code gets executed) slows down considerably when I enable this section of code, even if there are no files to add (hat is, even if fileAddList_ is empty). The update traversal time increases by an order of magnitude as a result.

However, if I comment out the call to sg::FileStampThread::addFiles, the slowdown goes away. Yet I've trapped the call in debug mode and it never gets executed.

So, I'm perplexed: why would a line of code inside a conditional affect my program execution speed when the conditional test fails and, by all appearances, it's never executed?

As a side note, I suspected it may have something to do with declaring the variable as a static, so I tried declaring it as a global (using extern) instead, to the same effect.


An edit to address some of the comments below:

  • The thread is an instance of an OpenThreads object. No MS-specific stuff, here. The instance is static.

  • addFiles() is not templated

  • I tested the loop with code in it. I commented out the lines alternately. I'm absolutely positive inclusion of the addFiles() call is the culprit.

  • Debug vs. Release is no different, pushing the code off into a separate function changed nothing, unfortunately.

  • OSG is high-performance and the comment about misprediction could be right on. Research forthcoming...

Code for the FileStampThread class:

void sg::FileStampThread::addFiles( sg::AssetFileList& files )
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock( contentMutex_ );

    for ( sg::AssetFileList::iterator it = files.begin(); it != files.end(); ++it )
    {
        if ( boost::filesystem::exists( (*it).getPath() ))
            fileList_.push_back( (*it) );
    }
};
Joel Graff
  • 239
  • 6
  • 14
  • Is FileStampThread in a COM department? And what kind of thread safety is used in that class (to make it a safe singleton)? – Yochai Timmer Mar 21 '12 at 11:49
  • 1
    It is quite hard to see without real access to the problem and the code. A simple answer to *why would it affect the speed* could be branch misprediction, but you would only notice it if this was executed in a tight loop. If this is inside some high performance code path, consider adding hints for the compiler. – David Rodríguez - dribeas Mar 21 '12 at 12:01
  • Well, in theory, if addFiles is a templated method, the fact that you're calling it somewhere will cause it to be instantiated. You could be doing other template instantiations inside addFiles which have global side-effects. That's a long shot though. – enobayram Mar 21 '12 at 12:25
  • When you comment out the call to `sg::FileStampThread::addFiles`, are you also commenting out the call to `fileAddList_.clear`? If so then the call to `fileAddList_.empty` is probably getting optimised away. – TonyK Mar 21 '12 at 12:36

1 Answers1

1

try to move the code:

sg::FileStampThread::instance()->addFiles( fileAddList_ );
fileAddList_.clear();

in a separate function a see if the problem persist. Hard to sat what is happening, same behavior on release and debug builds?

Marius
  • 833
  • 5
  • 11