Wednesday, November 5, 2014

Hot reloading C++

 Here is one approach to hot reloading of C++ that I use on my side project.
It is specific to Visual Studio.

This is useful if you want to rapidly iterate on some code, and don't enjoy continually restarting and navigating the program to whatever state it needs to be in to test the change.

It is based upon swapping DLL's and requires the ability to serialize state.

1. User modifies a C++ source file
2. File monitoring detects the change
3. Determines which projects are effected by the change.
4. Moves the existing DLL/PDB for those projects(they cannot be deleted as they are in use).
5. Fires up MSBuild to compile projects
6. Once Build Completes:
  • Build Fails:(
    • Build errors are propagated into the Visual Studio IDE
      • Have MSBuild dump out a text file containing the error msg
      • I use this command: /fl2 /fl3 /flp2:logfile=JustErrors.log;errorsonly /flp3:logfile=JustWarnings.log;warningsonly"
      • The msg is formated in a way that VS understands:)
      • Load the file in your game(JustErrors.log)
      • Use OutputDebugStringA to print it, this propagates it to VS, the error is now visible in the errors view
    • Old DLL/PDB moved back
  • Build Success:
    • Serialize state contained within relevant DLLs(into process owned memory)
      • Serializing and then unserializing the entire game state is the simplest route and avoids any potential conflicts with mixed state between DLL's. 
    • Destroy state associated with DLLs, and then unload the DLLs
    • Load new DLLs, create new state
    • Unserialize old state into the new state
    • Resume game
Rebuilds triggered by this process generally take about 1-2 seconds for my application, the exact time will depend your code.

**Visual Studio has a bug where it keeps the PDB loaded even if you unload the associated DLL.  So you can't delete the old PDB for any DLL you previously loaded, at least not while your game is running. Hopefully they fix this at some point.  

Saturday, October 4, 2014

Compiling C++ quickly in Visual Studio

Ensuring fast C++ build speed requires some effort--

Modules should improve the situation, but that is some years off(C++17 if we are lucky).

Here is what has worked for me(using Visual Studio)
This is intended for a rapid iteration build, a build you intend to ship would not use these settings.
  • Enable /MP Multiprocessor builds. 
  • Disable Global optimizations
  • Incremental Linking (/INCREMENTAL) and Use Library Dependency Inputs(Yes)
  • Add /Zc:inline  to command line of compiler
  • Linker->Optimizations: References(No), COMDAT Folding(No)
  • Pre-Compiled Headers(PCH). Put rarely modified files in the PCH, but include everything you can possible include. Test the compilation times of files that use the PCH. You can enable this in Visual Studio(*2). Try to get it as low as possible.
  • Limit the headers you include, especially avoid including headers within headers
  • Forward declare everything that can be, even types passed by value can be forward declared
  • Do not create "registry files". *example: a file containing an enum with an entry for each type of component in your engine. If you do this, you will need to add an entry to this file each time you create a new component, which will result in a large and often triggered rebuild cycle.
  • If you find yourself calling from Module A to an object in Module B, but only doing so once, think about wrapping that access in a C function call. The C function can be placed in Module B, then either declared extern within Module A, or a separate header can be created if it is likely that this C function will be called multiple times. This reduces coupling between files. Changes to A will not trigger a recompilation of B.
  • /PDBCOMPRESS slows the linker down, should probably not use this
  • Use type erasure to reduce coupling & generate less code. For none performance critical paths, a single type erased path can be preferable to a template path per type.  
  • Focus on optimizing the build speeds of any commonly used templates. There are multiple things you can do here.
    • Some templates can be simple wrappers around a none templated type or function, which is itself implemented in a .cpp file, and thus not inline.
    • Use variadic templates to replace old style overloads based on # of arguments.
    • If there exists a finite set of types that the template can be instantiated with, try explicit template instantiation.
Templates are commonly accused of killing build times.
This is not very accurate, the real culprit is headers. Since templates exist in headers it gives the false impression templates are at fault.
 Once you have solved the exponential build time issue caused by headers, templates have a only a small effect on build times.

*2: To enable build timings: 
Tools -> Options -> Projects and solutions ->VC++ Project Settings->Build timing->yes

**Tools -> Options -> Projects and Solutions -> Build and Run and set the MSBuild project build output verbosity to "Normal"** 

Friday, October 3, 2014


Various voxel landscapes I made recently.
The carving tool is still pretty basic so I can't do anything impressive yet.
You basically can select from 5 shapes + 4 blend ops.  
But it works in real time so I can fly about and apply these ops and see the result immediately.

Thursday, October 2, 2014

Chile & Argentina

Here is a link to my friends blog detailing our three month trek in South America.
Photos include famous stuff like Torres Del Pine, Tierra Del Fuego, and Fitz Roy.

Probably the most memorable bits:
-trekking through lava flows created by the 2011 eruption of Volcan Pueyhue;  40 mph winds filled with ash, visibility was almost nothing, we would stumble to the edge of chasm, gaze down, and have no idea how deep it was:) Had to use GPS/compass to navigate our way.
-living in a tiny hut on a glacier for five days crammed with 12  people, waiting for a storm to pass--

Lots of nice photos on his blog
Snowfall in Tierra Del Fuego
Poking my way across a glacier