Horde3D

Next-Generation Graphics Engine
It is currently 10.11.2024, 20:44

All times are UTC + 1 hour




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: 04.10.2009, 09:06 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
This is a small test we did once: non-blocking/asynchronous file loading. While a new resource is read from disk, at the same time the resource that was loaded before is parsed. In theory this should bring some speedups, especially when reading from slow media. However, I did not really notice any improvement when loading a limited amount of data from HDD (HDDs are much faster than optical media). Furthermore, the async loading code is very platform dependent and only works on Windows right now (Linux has some special functions as well). So we decided to not put it into the h3dutLoadResourcesFromDisk function, to keep the code there simple. Anyway, maybe the code is useful for someone, so I post it here:

Code:
#ifdef PLATFORM_WIN  // Do asynchronous file loading on Windows

   HANDLE hFile = INVALID_HANDLE_VALUE;
   OVERLAPPED overlapped;
   char *data0 = 0x0, *data1 = 0x0;
   int size0 = 0, size1 = 0;
   int res0 = 0, res1 = 0;
   
   while( h3dQueryUnloadedResource( 0 ) != 0 )
   {
      // Wait until previous file reading request has finished (if any)
      if( hFile != INVALID_HANDLE_VALUE )
      {
         if( !HasOverlappedIoCompleted( &overlapped ) ) continue;
         CloseHandle( hFile ); hFile = INVALID_HANDLE_VALUE;
      }

      // Start reading next resource
      res1 = h3dQueryUnloadedResource( res0 == 0 ? 0 : 1 );
      if( res1 != 0 )
      {
         // Loop over search paths and try to open files
         for( unsigned int i = 0; i < dirs.size(); ++i )
         {
            string fileName = dirs[i] + resourcePaths[h3dGetResType( res1 )] + "/" + h3dGetResName( res1 );
            hFile = CreateFile( fileName.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING,
                                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN, 0 );
            if( hFile != INVALID_HANDLE_VALUE ) break;
         }
         
         if( hFile != INVALID_HANDLE_VALUE )
         {
            // Start asynchronous reading
            ZeroMemory( &overlapped, sizeof( OVERLAPPED ) );
            size1 = GetFileSize( hFile, 0x0 );
            data1 = new char[size1 + 1];
            ReadFile( hFile, data1, size1, 0x0, &overlapped );
         }
         else
         {
            // Tell engine that file could not be found
            h3dLoadResource( res1, 0x0, 0 );
            result = false;
            data1 = 0x0; size1 = 0; res1 = 0;
         }
      }

      // Load current resource
      if( res0 != 0 )
      {
         data0[size0] = '\0';  // NULL-terminate for XML
         result &= h3dLoadResource( res0, data0, size0 + 1 );
         delete[] data0;
      }

      // Set next resource as current resource
      data0 = data1; size0 = size1; res0 = res1;
   }

#else  // Standard (blocking) file loading


Top
 Profile  
Reply with quote  
PostPosted: 04.10.2009, 12:44 
Offline

Joined: 22.11.2007, 17:05
Posts: 707
Location: Boston, MA
Non-blocking file I/O on Linux/Mac is just a matter of putting the file descriptor in non-blocking mode (using fnctl), and then calling read() until it stops returning EWOULDBLOCK.

While you probably won't see any performance gains over blocking I/O, the important part is that you can continue rendering while loading, all without spawning a huge number of threads.

_________________
Tristam MacDonald - [swiftcoding]


Top
 Profile  
Reply with quote  
PostPosted: 15.10.2009, 16:12 
Offline

Joined: 22.11.2007, 17:05
Posts: 707
Location: Boston, MA
Thinking about it, a simpler way to perform asynchronous I/O on Mac/linux is to open a file descriptor as normal, and use select() to determine when it is ready to read from (just as you would do with a socket).

_________________
Tristam MacDonald - [swiftcoding]


Top
 Profile  
Reply with quote  
PostPosted: 17.10.2009, 10:36 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
Thanks for the hints swiftcoder!

If someone wants to provide an asynchronous version for linux/mac we can integrate it. However, as stated before, it does not bring a huge advantage when just loading from HDD.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group