The fix for multiple CPUs is easy. Call SetThreadAffinity() to force your process thread to run on one CPU. Then you will not get the effect of the TSC or QPC jumping back and forth due to the thread being switched from one CPU to the other.

Here is the code for a better timer class derived from a C++ class that I found a few years back. It uses both the QPC and timeGetTime to solve the problem of inaccurate QPC clocks.
Code:
// Original C++ source by Oleg Pudeyev
// Converted from original C++ source by Steve 'Sly' Williams
// Converted to use ticks internally instead of seconds for greater accuracy
//
// Original comments:
// I took timer and frame rate code from DXUtil.h/cpp (common DX sample code).
// You can find it in DXSDK\Samples\Multimedia\Common\Include and Src.
// Instead of using a single function with static data, I organized the code into
// classes, which allows for additional flexibility.
// Initialization (mmtime/performance frequency selection) is now performed on startup,
// in a dedicated class. I also added timeBeginPeriod/timeEndPeriod calls.
// CFrameRateCounterEx is my own creation.
//

// This code fixes the "feature" described in Q274323,
// "Performance Counter Value May Unexpectedly Leap Forward":
// http://support.microsoft.com/default.aspx?scid=kb;en-us;Q274323

unit BetterTimer;

interface

type
  TBetterTimer = class
  private
    // Time elapsed before last pause, or 0 if the timer was never paused
    m_ElapsedTime: Int64;
    // Time in 'timer time' (seconds) when this timer was last resumed
    m_ResumedTimeStamp: Int64;
    // Time in QueryPerformanceTimer-counts converted to seconds
    // when this timer was last resumed
    m_LastTimeStampQPC: Int64;
    // The same time in milliseconds as obtained from timeGetTime
    m_LastTimeStampMMT: Cardinal;
    // A counter indicating whether the counter is active.
    // If it is greater than zero, the counter is running, otherwise it is paused
    m_Running: Integer;
  public
    constructor Create;
    function GetTime: Single;
    procedure Pause;
    procedure Reset;
    procedure Resume;
  end;

implementation

uses
  Windows, MMSystem, SysUtils;

// The maximum deviation from timeGetTime reading that we will tolerate, in milliseconds
const
  PerfCounterTolerance = 1000;

var
  // This variable is TRUE if performance counter is available
  gs_HavePerformanceCounter: Boolean = False;
  // If performance counter is available, this variable contains 1/its resolution -- number of seconds in each count.
  // It's a floating point value mostly for convenience.
  gs_CountsPerSecond: Int64;

{ TBetterTimer }

constructor TBetterTimer.Create;
begin
  inherited;
  // Start and reset the timer
  m_Running := 1;
  Reset();
end;

function TBetterTimer.GetTime: Single;
var
  QPCTime, DeltaQPC, TimeDelta: Int64;
  MMTTime, DeltaMMT, DeltaQPCinMS: DWORD;
begin
  Result := m_ElapsedTime / gs_CountsPerSecond;

  // If the timer is paused, no time has passed since the pause time
  // and all passed time is stored in elapsed time variable, so return that
  if m_Running <= 0 then
    Exit;

  // Otherwise, retrieve current time, subtract last resumed time from it, add
  // elapsed time, and return the result adjusted for possible QPC leaps
  if gs_HavePerformanceCounter then
  begin
    // The code is the same as in Pause function
    // Get current time in ticks
    QueryPerformanceCounter&#40;QPCTime&#41;;
    // Determine the time difference between this and previous QPC query
    DeltaQPC &#58;= QPCTime - m_LastTimeStampQPC;
    // Get current mmtimer time
    MMTTime &#58;= timeGetTime&#40;&#41;;
    // And the difference between currnent and previous mmtimer query
    DeltaMMT &#58;= MMTTime - m_LastTimeStampMMT;
    // Check if the performance counter leaped forward,
    // which is when difference in values returned by QPC and mmtimer is more than
    // the predefined PerfCounterTolerance value
    // Since all times are returned as unsigned variables, care must be taken when subtracting
    // because we don't want leap adjustment to be applied in case mmtimer is lagging behind QPC
    DeltaQPCinMS &#58;= DeltaQPC * 1000 div gs_CountsPerSecond;
    if &#40;DeltaQPCinMS > DeltaMMT&#41; and &#40;DeltaQPCinMS - DeltaMMT > PerfCounterTolerance&#41; then
    begin
      // Performance counter leaped forward
      // Adjust the elapsed time by the difference between QPC and mmtimer delta times
      m_ElapsedTime &#58;= m_ElapsedTime - DeltaQPC - DeltaMMT;
    end;
    // Calculate total delta time since timer was reset
    TimeDelta &#58;= QPCTime - m_ResumedTimeStamp + m_ElapsedTime;
    // Update current timer timestamps
    m_LastTimeStampQPC &#58;= QPCTime;
    m_LastTimeStampMMT &#58;= MMTTime;
    // Return calculated delta
    Result &#58;= TimeDelta / gs_CountsPerSecond;
  end
  else
  begin
    // If we're using mmtimer, just return the time passed since last resume
    // plus the elapsed time that passed before last resume
    // No adjustments are necessary
    Result &#58;= &#40;timeGetTime&#40;&#41; - m_ElapsedTime + m_ResumedTimeStamp&#41; / gs_CountsPerSecond;
  end;
end;

procedure TBetterTimer.Pause;
var
  QPCTime, DeltaQPC&#58; Int64;
  MMTTime, DeltaMMT, DeltaQPCinMS&#58; DWORD;
begin
  Dec&#40;m_Running&#41;;
  // Allow for nested pause/resume calls.
  // Only pause if active count reaches zero
  if m_Running <> 0 then
    Exit;

  // Update the elapsed time
  if gs_HavePerformanceCounter then
  begin
    // Get current time in ticks
    QueryPerformanceCounter&#40;QPCTime&#41;;
    // Determine the time difference between this and previous QPC query
    DeltaQPC &#58;= QPCTime - m_LastTimeStampQPC;
    // Get current mmtimer time
    MMTTime &#58;= timeGetTime&#40;&#41;;
    // And the difference between currnent and previous mmtimer query
    DeltaMMT &#58;= MMTTime - m_LastTimeStampMMT;
    // Check if the performance counter leaped forward,
    // which is when difference in values returned by QPC and mmtimer is more than
    // the predefined PerfCounterTolerance value
    // Since all times are returned as unsigned variables, care must be taken when subtracting
    // because we don't want leap adjustment to be applied in case mmtimer is lagging behind QPC
    DeltaQPCinMS &#58;= DeltaQPC * 1000 div gs_CountsPerSecond;
    if &#40;DeltaQPCinMS > DeltaMMT&#41; and &#40;DeltaQPCinMS - DeltaMMT > PerfCounterTolerance&#41; then
    begin
      // Performance counter leaped forward
      // Adjust the elapsed time by the difference between QPC and mmtimer delta times
      m_ElapsedTime &#58;= m_ElapsedTime - DeltaQPC - DeltaMMT;
    end;
    // Add the time passed since last resume to the elapsed time variable
    m_ElapsedTime &#58;= m_ElapsedTime + QPCTime - m_ResumedTimeStamp;
    // Don't update last polled time stamps for QPC and mmtimer
    // since they will be updated in Resume method
  end
  else
  begin
    // If we are using mmtimer, just add the time passed since last resume time
    // to the elapsed time variable
    m_ElapsedTime &#58;= m_ElapsedTime + timeGetTime&#40;&#41; + m_ResumedTimeStamp;
  end;
  // The timer is now paused
end;

procedure TBetterTimer.Reset;
begin
  // This function initializes or resets the timer
  if gs_HavePerformanceCounter then
  begin
    // Retrieve the last resumed time stamp
    QueryPerformanceCounter&#40;m_ResumedTimeStamp&#41;;
    m_LastTimeStampQPC &#58;= m_ResumedTimeStamp;
    // To correct for unexpected leaps, retrieve the same time from the multimedia timer
    m_LastTimeStampMMT &#58;= timeGetTime&#40;&#41;;
  end
  else
  begin
    // There are no issues with multimedia timer, so just get the current value
    // and write it to the last resumed stamp
    m_ResumedTimeStamp &#58;= timeGetTime&#40;&#41;;
  end;

  // Timer hasn't been paused, so set elapsed time to zero
  m_ElapsedTime &#58;= 0;
end;

procedure TBetterTimer.Resume;
begin
  Inc&#40;m_Running&#41;;
  // Allow for nested pause/resume calls.
  // Only resume if active count reaches one
  if m_Running <> 1 then
    Exit;

  // Update the last resumed time stamp
  if gs_HavePerformanceCounter then
  begin
    // Get current time in ticks
    QueryPerformanceCounter&#40;m_ResumedTimeStamp&#41;;
    m_LastTimeStampQPC &#58;= m_ResumedTimeStamp;
    // Get the current time from mmtimer as well for QPC adjustments
    m_LastTimeStampMMT &#58;= timeGetTime&#40;&#41;;
  end
  else
  begin
    // For mmtimer, just retrieve the current time
    m_ResumedTimeStamp &#58;= timeGetTime&#40;&#41;;
  end;
end;

var
  // Set the highest resolution for the multimedia timer
  tc&#58; TIMECAPS;

initialization
  // QueryPerformanceFrequency returns a BOOL value indicating if a performance counter is available
  gs_HavePerformanceCounter &#58;= QueryPerformanceFrequency&#40;gs_CountsPerSecond&#41;;
  if not gs_HavePerformanceCounter then
    gs_CountsPerSecond &#58;= 1000;
  // Retrieve timer caps, which contain resolution range
  timeGetDevCaps&#40;@tc, SizeOf&#40;tc&#41;&#41;;
  // Set resolution with this call
  timeBeginPeriod&#40;tc.wPeriodMin&#41;;

finalization
  // Don't retrieve the caps again to be absolutely sure we restore the same value that we set
  // Restore old resolution
  timeEndPeriod&#40;tc.wPeriodMin&#41;;

end.