Tuesday, April 22, 2014

RAD Telemetry 2.0L released!

Telemetry 2.0L has just been released.  This is strictly a minor maintenance release to deal with some small bugs.

NOTE: The ABI has changed, so be sure to recompile/relink everything instead of just swapping out libraries!

Run Time

  • Bugfix: varargs with float types were not handled properly at times on OS X (64-bit), Linux/x64 and PS4
  • Bugfix: TM_VA_LIST parameters were incorrectly warned as 'stack variables' by checked build
  • Change: Android runtime is now built with -funwind-tables by default
  • Enhancement: checked build now does extra verification to watch for 'wrapper' related bugs

Server

  • Bugfix: unknown string pointers are silently handled instead of generating an exception and associated disconnection
  • Bugfix: locks/timespans could accidentally start with a negative ref count

Visualizer

  • Enhancement: 'edit source code' is now a right-click zone option
  • Bugfix: backgrounds were drawn in green instead of black of any timeline sections were present but the current visible area did not have one defined
  • Bugfix: tooltip was not showing file name and line properly in zone view
  • Bugfix: in some situations Visualizer on Windows would leave clipboard open, locking out other applications from copy/paste

Other

  • Change: added documentation discussing the perils of wrapping calls to Telemetry vs. just using Telemetry in place

Monday, March 31, 2014

RAD Telemetry 2.0K is out!

Telemetry 2.0K is out the door!  The biggest new feature is context switch trapping support on PS4, putting it on a par with Windows and 360.  Also, the directory/file naming structure is no longer so rigid (so you can rename directories and TDB files).  Finally, fetch times for very dense sets of plots, zones, and messages are way faster now.  Some fetches that used to take 15 seconds now take < two seconds!

Note that the server/Visualizer/run-time need to be simultaneously upgraded since there is a small change in the protocol.

Run Time

  • Enhancement: context switch capture on PS4
  • Enhancement: add server configuration API (tmSetServerConfiguration)
  • Bugfix: fixed bug where timespans could hang the run-time if tmOpen was called late
  • Change: linux (and other BSD-ish) network implementation now spew debug on wouldblock (checked build)
  • Change: disabled network policy on PS4 telemetry socket
  • Enhancement: added TM_VAR macro and no longer exclude tmtypes.h on NTELEMETRY.  This means you can wrap Telemetry declarations and variables in a way that is compatible with NTELEMETRY, e.g TM_VAR(TmU64 x);

Server

  • Change: unknown strings are a bit more known (null vs. unrecognized)
  • Enhancement: decoupled sessions from their filenames, so you can now rename files/directories (yay!)
  • Bugfix: fixed crash bug with oversized messages
  • Bugfix: generated mem usage plots (via TMZF_MEM_REGION_EXPERIMENTAL) were using incorrect paths

Visualizer

  • Enhancement: mousewheel now works in message view
  • Enhancement: greatly sped up fetch times for zones, messages, plots, and mem events
  • Enhancement: session notes are now on a separate line and green, and if then completely skipped
  • Change: disable 'copy' button in message pane until all have arrived
  • Change: messages without newlines now have newlines appended automatically
  • Bugfix: fixed file/line missing from zone tooltips


Thursday, February 20, 2014

RAD Telemetry 2.0j released!

This is a minor maintenance and bugfix release, but it does require a recompile/relink.

Run Time

  • Enhancement: tmMessage now has a tmMessageEx variant. This was added so you can change zone label/sublabels in virtual threads.
  • Enhancement: (Windows) you can now specify full path for TMDATA files when using TMCT_FILE captures
  • Bugfix: fixed benign AppVerifier warning about dangling CriticalSection

Server

  • Bugfix: in certain situations long zones would not be recorded properly
  • Bugfix: fixed pathological edge case in zone garbage collector leading to N^2 processing times

Visualizer

  • Change: (Windows) Visualizer now uses system default text editor instead of Notepad when editing notes
  • Enhancement: plot scale with mousewheel should work now
  • Bugfix: double clicking a frame in plot view would sometimes take you to the wrong location
  • Bugfix: right-click 'zoom' on plot would sometimes take you to the wrong location

Other

  • Enhancement: Mac/Linux/Win now have gpu_opengl.cpp sample file included in distributions
  • Enhancement: Python SQLite export script has been greatly enhanced
  • Change: 'tools' only distributions now included exporter script
  • Change: updated zone filtering documentation
  • Change: updated timespan document to note the ordering constraints of *TimespanAt APIs


Tuesday, February 11, 2014

Dynamic Strings: Solution to a Problem and a Problematic Solution Combined

Telemetry's run-time markup system relies on the assumption that string identifiers are both constant and (hopefully) string pooled.  This allows us to send over a string only once when we encounter it, e.g.:

void foo( void )
{
   tmZone( cx, TMZF_NONE, "hello world" ); // "hello world" should be sent only the first time we see it

   // do a bunch of foo stuff
}

This works great for the general case where you're statically marking up a lot of code, which is common when using compiler provided constants like __FUNCTION__.

However sometimes the description you pass to tmEnter or tmZone isn't a const string (e.g. it may be copied out of string table, etc.).  Or (more likely) one of the string parameters you're passing to your zone markup isn't actually a const string and instead a string on the stack.

void foo( char const *name )
{
   // if 'name' points to something on the stack, this may be bad...
   tmZone( cx, TMZF_NONE, "foo: %s", name );
   // do a bunch of foo stuff
}

Here's where the problem occurs.  Since Telemetry assumes that the string pointers passed to it are const, it will try to read from name in its background processing thread probably long after name is out of scope and gone.  In addition, once it sees name's address, it won't send it again.  This is to save a lot of bandwidth, but if the contents of name are constantly changing (which is highly likely) you'll see a lot of the same string repeating in the Telemetry Visualizer (since it's never resent with the new content) instead of the updated string.

(Instead of just using the pointer we could hash the contents, but that has a surprising amount of overhead when working with lots of strings, particularly on lower end devices)

Telemetry's solution to this problem is to allow you to tag certain strings as dynamic, i.e. volatile memory that may change or disappear almost immediately.

void foo( char const *name )
{
   tmZone( cx, TMZF_NONE, "foo: %s", tmDynamicString( cx, name ) );
   // do a bunch of foo stuff
}

Now the full contents of name are sent over immediately every time they're encountered.  In exchange for correctness we've now incurred a potentially massive amount of network overhead.  This is fine as a first pass integration (to make sure your markup is working), but if you leave it in and have a lot of markup you may find that Telemetry is suddenly eating a tremendous amount of network bandwidth due to redundant string sends.  This is really a problem on devices with limited bandwidth to begin with such as WiiU, XBOX 360, and mobile.

Figuring all this out can be a headache, so thankfully Telemetry's server automatically generates plots indicating the amount of dynamic string activity in a session.  If you enable the plots you should be able to see if you're hammering the dynamic string system or not.  A few dozen dynamic strings should be fine, but if you're finding that you're sending over hundreds or thousands of strings every frame, that is likely bad.


If you find yourself in this situation then you'll want to invest some time doing a string pooling/interning system that provides a const mapping from a volatile string to a static one.  There's no easy way for Telemetry to provide this functionality since it depends heavily on your app's underlying string management architecture, but it's a worthwhile investment for the performance.

Tuesday, February 4, 2014

RAD Telemetry 2.0i released!

Whoops, that was quick.  This is an interim bug fix release with some minor new features.  The big issues are that plot generation was crashing, so that's been fixed, and we've allowed you to prefetch a lot more data per server data fetch which reduces latency when just scrolling around in the zone view.

Run-Time

  • Change: QNX/ARM is now built with -fpic
  • Change: removed dependency on dbghelp.dll for Windows
  • Change: 'processing time' plot is now 'process time(ms)'

Server

  • Change: default zone pool is larger now, reducing need to resize continuously

Visualizer

  • Bugfix: plot generation was crashing
  • Change: generated plot names are shortened and now include 'by frame' or 'by time' unit
  • Enhancement: prefetch window can be altered to reduce latency when scrolling around.  This is a slider in the Options page.
  • Enhancement: state tag backgrounds in zone view are more prominent
  • Bugfix: mem track button would disappear and stay gone
  • Bugfix: time scale calculations were off in certain rare instances due to quantization artifacts

Other

  • Change: updated docs on using regsrv32 to fix MS DIA SDK registration issues

Tuesday, January 28, 2014

RAD Telemetry 2.0h released!


Telemetry 2.0h has been released!  This is a collection of small fixes/updates from December and through January.  Updated to support the latest console SDKs, implemented a bunch of customer requests, updated and clarified some documentation, etc.  This will hopefully be the basis for the latest 2.0 stable build so I can start working on 2.1.

NOTE: This requires a full rebuild!  The ABI has changed slightly to support the tmPlotAt functionality, so please remember to update your headers and libraries simultaneously and perform a full rebuild.

The only really significant gotcha is that TMZF_PROFILER_ONLY zones are now effectively discarded by the server, since they were a Telemetry 1.x specific feature.  A similar feature may be forthcoming in Telemetry 2 but because some of the constraints have changed (we no longer have monolithic frames like we did in Telemetry 1.x) it'll have to be designed a little differently.

Run-Time

  • Enhancement: added tmPlotAt APIs so you can retroactively place a plot in time.  For example, you might want to accumulate some information but then plot it back where it's most relevant, not where it's available.
  • Enhancement: updated to latest platform SDKs.
  • Bugfix: fixed XB1 checked build link errors
  • Change: 64-bit Linux static lib is now built with -fPIC

Server

  • Enhancement: server now does periodic flushing every 100ms instead of only flushing on tmTick processing
  • Change: TMZF_PROFILER_ONLY zones are now explicitly discarded

Visualizer

  • Enhancement: user defined zone, timespan, and plot colors.  By putting "color: rrggbb" in your description the Visualizer will color accordingly.
  • Enhancement: added sort-by option in profiler results pane so you can sort by time or count
  • Enhancement: plot tooltip now shows time offset from start of session (so like T1 you can now see how far in a frame is, not just its duration)
  • Enhancement: TMZF_IDLE zones are now more obvious
  • Enhancement: 'show idle zones' checkbox is back
  • Enhancement: selected region in zone view will display its duration in tooltip
  • Enhancement: 1ms tick intervals are now drawn in the zone view
  • Bugfix: profiler pane now shows correct counts for accumulation zones

Other

  • Change: updated docs to clarify that TMZF_PROFILER_ONLY is a T1 specific feature

Wednesday, December 11, 2013

RAD Telemetry 2.0g released!


Telemetry 2.0g has been released!  Big performance increase during processing (~40% faster) and bug fixes.

Run-Time

  • Change: tmInitializeContext now prints warning (checked build only) if the user provided buffer is greater than 4MB.  Buffers that are too large can cause unnecessary slow downs.
  • Bugfix: PS3: issuing multiple tmOpen/tmClose calls after initiating the PPU listener thread would hang the run-time
  • Bugfix: Linux: intermittent hang bug that happened on a small number of systems when scanning processes during tmOpen

Server

  • Enhancement: SQLite usage optimizations resulting in a significant speed up during cooking (~40%)
  • Change: TMZF_MEM_REGION_EXPERIMENTAL now uses path name for naming allocations if present (a la profiler names)
  • Change: shortened generated filenames in an attempt to stave off MAX_PATH issues on Windows
  • Change: autogenerated memory usage plots are signed 64-bit instead of unsigned
  • Change: dynamic string usage is now plotted to help narrow down bandwidth issues
  • Bugfix: string cache overflow bug would make some plots disappear if you had too many unique strings
  • Bugfix: sort order was incorrect for profiler queries, so important data was clipped off if there were a lot (>512) of results in a profiler fetch
  • Bugfix: fixed issues where spurious plots were generated for mem usage

Visualizer

  • Change: cooking now reports number of files left instead of the approximate percentage
  • Bugfix: mouse wheel no longer zooms if UI is in modal state
  • Bugfix: you could erroneously select live sessions by clicking 'all' button
  • Bugfix: fixed rare crash bug in Visualizer that resulted from trying to access non-existent session data

Other

  • Change: TMS API changed to better support querying for cooking session duration
  • Change: updated UE3 integration docs with clarifications
  • Bugfix: updated trylock docs to indicate that they don't support recursive mutexes