Monday, December 19, 2011

Debugging VBScript

This blog post only exists to prevent expired linking. My blog has moved to: http://pabloaizpiri.com/

--------------------------------------------------------------------------------

Unfortunately, sometimes I still have to work with VBScript. It actually isn't so bad for quickly whipping up a script that runs on a schedule to perform some sort of minor task. Sometimes it comes in handy to debug the script, and I'm making an entry on it for future reference. (A coworker showed me this)


1.) Make sure you set your VS settings as follows in Tools -> External Tools:
VSSettings.jpg
2.) Set your Internet Explorer settings accordingly:
IESettings.jpg

3.) Load the script you wish to debug into Visual Studio... make sure it is VALID syntax or you'll never even hit the break point.
4.) Set your break points.
5.) Go to Tools -> VBSCript_Debugger to begin debugging.
NOTE: When you hit "stop", it will not actually stop script execution- only the debugging session- to actually stop the script from continuing, use the Immediate window to execute "wscript.quit".
You can also start the debugger on a server that does not have Visual Studio running by starting up a command prompt and firing up the VBScript debugger manually:
wscript.exe //d c:/test.vbs
You'll need to set a break point. (The command is "Stop" and you can add it anywhere in your script). This should automatically fire up the Microsoft Visual debugger if installed; if not you can download it from the Microsoft website.
As a final note, remember that often time errors in script are due to the account they are running under.  This one's caused me to spin my wheels for linger that I wanted to until I realized my scheduled task was running under credentials preventing it from completing part of its job... it's always the simple things. :P

Saturday, December 17, 2011

What Can't be Measured Can't be Improved: Investing in Measurement

This blog post only exists to prevent expired linking. My blog has moved to: http://pabloaizpiri.com/

--------------------------------------------------------------------------------

For sure we have all heard the saying and know it well- but few of the times do we apply it- especially if measuring (or making measuring easy) is going to take some work up front. We like to think we can "cowboy" it and figure out where out performance-hitting bugs are ourselves.

Today, I worked on my 3D engine most of the day. I had a blast and a lot of good came from all the work I put into it. Even though I still have a ways to go, I felt like I had gotten to the point where it was time to start measuring performance.

Performance is a pretty important topic for a 3D application- and especially considering I'm just starting out learning the ins and outs of DirectX (and to add insult to injury, I'm using a managed language), I wanted to make sure I'm writing fairly efficient code. I've learned not to micro-optimize, and I felt like now that I had gotten the basic concepts down and working I would begin profiling.

At first I was going to just insert a few Diagnostics.Stopwatch calls here and there but after thinking it through I decided that as important as performance was for a 3D engine, it would most likely be in my best interest to create a class to make measuring the performance of the engine very easily. This is important because as you're working, (if the use of your diagnostics class is easy enough), you will also be encouraged to add metrics to your application. I've realized that the time spent up-front to do this is invaluable, especially since I know I will use this class plenty in the future.

My approach was fairly simple- I knew it had to be something that was super easy to use or it would have a low ROI, but I also knew it had to provide valuable performance metrics and information, not just data.
Essentially it has four major timing calls:

  • public void BeginSingle()
  • public void EndSingle(string Name)
  • public void BeginSpecific(string Name) 
  • public void EndSpecific(string Name)

BeginSingle and EndSingle make timing a certain portion of code very easy. For example, say I want to measure a piece of code that calculates what should be hidden in a scene:

            TimingObject.BeginSingle();
     [..code that calculates visibility ...]
     TimingObject.EndSingle("CalculatingHiddenObjects");

The string passed to "EndSingle" will ensure that value it attached to some identifier. Now, if I need to nest between timings, I can use BeginSpecific and EndSpecific:

            TimingObject.BeginSpecific("TotalTime");
     TimingObject.BeginSingle();
     [..code that calculates visibility ...]
     TimingObject.EndSingle("CalculatingHiddenObjects");
     TimingObject.BeginSingle();
     [..other stuff ...]
     TimingObject.EndSingle("OtherCalculations");
     TimingObject.EndSpecific("TotalTime");

This model has worked remarkably well. Additionally, built into the class I have code that stores the times in an array and averages them, as well as takes note of the max and min values. The class also has a function to output all values to a text file, and provide percentages based on the total frame and entity render times sorted by the most expensive- this was a very useful feature for me!

Results? I have improved my code to where it is over 5x faster! Huge difference! It came much more in line with what I was hoping for. I'm very happy, and I was able to make excellent use of my time while learning some great lessons on how to write my DirectX code more efficiently. In line with the 80/20 "rule", indeed, about 80% of my bottle neck was in about 20% of my code. In the most complex scene I tested, I went from about 120 FPS, to about 680! That's a 566% improvement after about 25 minutes of constantly optimizing by testing out different things and looking through the generated performance log.

In closing, I felt like this was a successful approach I want to repeat again in other areas: first I learned how to write code that accomplished my goals without having to think about performance and I didn't waste my time micro-optimizing. Then, when I was ready, I invested some time up front to write a tool that made generating, collecting, and reading metrics easily and used that to tackle optimization. The 30 minutes that I spent up-front writing my timing class was definitely worth it in the end, and I would dare say probably saved me plenty of time.


JDX Update: Limited Gile[s] support in Engine

This blog post only exists to prevent expired linking. My blog has moved to: http://pabloaizpiri.com/

--------------------------------------------------------------------------------

Another tool that I used to love working with was 3D Gile[s] . It's a light mapper, and you can use it to build 3D scenes and light them. So I started working on support to import 3D Gile[s] scenes. Even though I'm still working through bugs and this scene import is not 100% yet, here's a screen shot of my progress so far:





Also did some minor optimizations of the engine itself.  EDIT: [These minor optimizations were before the major optimizations I made by profiling]