简体   繁体   中英

SetLocalTime causing PC to lag, how can I optimize it?

I want to create a program that will slow down Windows' time. I will be using SetLocalTime() for this. However, when I open the program, my PC starts to micro-stutter and game performances drops even though the process isn't using nearly any CPU.

#include <iostream>
#include "Windows.h"
#include <thread> 
#include <chrono>
using namespace std;

SYSTEMTIME st;
WORD hour;
WORD minute;
WORD second = 0;

int main()
{
    GetLocalTime(&st);
    hour = st.wHour;
    minute = st.wMinute;
    second = st.wSecond;

    for (;;)
    {
        for (int i = 0; i < 4; i++)
        {
            this_thread::sleep_for(chrono::milliseconds(500));
            st.wHour = hour;
            st.wMinute = minute;
            st.wSecond = second;
            SetLocalTime(&st);
        }
        second++;
        if (second == 60)
        {
            second = 0;
            minute++;
        }
        if (minute == 60)
        {
            minute = 0;
            hour++;
        }
    }
}

If you change the system clock, all the programs that use it for timing will also slow down.

From your comments, I could gather that you wish to time scale an application that uses time. So far, you didn't get more specific, so I cannot suggest anything more than a general approach.

Create a time manager class that, when you start your application, gets the current system time and store it as the base time of your application. Instead of using GetLocalTime() or GetSystemTime(), create a method in your class that will return the current time based on a time dilatation factor.

class TimeManager
{
  private:
    SYSTEMTIME _BaseTime;
    double _TimeDilatation;
  public:
    TimeManager();
    void SetTimeDilatation(double timeDilatation);
    void GetTime(LPSYSTEMTIME lpSystemTime);
};

// Constructor will get the current local time.
TimeManager::TimeManager()
{
  GetLocalTime(&_BaseTime);
}

// Sets the time dilatation factor.
// 0.0 to 0.9 time will slow down
// 1.0 normal flow of time
// 1.1 to max double, time will go faster
void TimeManager::SetTimeDilatation(double timeDilatation)
{
  _TimeDilatation = timeDilatation;
}

// Get the current time taking into account time dilatation
void TimeManager::GetTime(LPSYSTEMTIME lpSystemTime)
{
  SYSTEMTIME resultingTime;
  SYSTEMTIME realTime;

  FILETIME ftime;
  ULARGE_INTEGER uliTime;
  __int64 lowerValue, higherValue, result;

  // Get the current local time
  GetLocalTime(&realTime);

  // Translate the base time into a large integer for subtraction
  SystemTimeToFileTime(&_BaseTime, &ftime);
  uliTime.LowPart = ftime.dwLowDateTime;
  uliTime.HighPart = ftime.dwHighDateTime;
  lowerValue = uliTime.QuadPart;

  // Translate the current time into a large integer for subtraction
  SystemTimeToFileTime(&realTime, &ftime);
  uliTime.LowPart = ftime.dwLowDateTime;
  uliTime.HighPart = ftime.dwHighDateTime;
  higherValue = uliTime.QuadPart;

  // Get the time difference and multiply the dilatation factor
  result = (higherValue - lowerValue) * _TimeDilatation;
  // Apply the difference to the base time value
  result = lowerValue + result;

  // Convert the new time back into a SYSTEMTIME value
  uliTime.QuadPart = result;
  ftime.dwLowDateTime = uliTime.LowPart;
  ftime.dwHighDateTime = uliTime.HighPart;
  FileTimeToSystemTime(&ftime,&resultingTime);

  // Assign it to the pointer passed in parameter, and feel like a Time Lord.
  *lpSystemTime = resultingTime;
}

int main()
{
  TimeManager TM;
  TM.SetTimeDilatation(0.75f); // the time will pass 75% slower

  for (;;)
  {
    SYSTEMTIME before, after;

    TM.GetTime(&before);
    
    // Do something that should take exactly one minute to process.

    TM.GetTime(&after);

    // Inspect the value of before and after, you'll see
    // that only 45 secondes has passed
  }
}

Note that it's a general idea to push you in the right direction. I haven't compile that code, so there maybe an error or five. Feel free to point them out, and I'll fix my post. I just didn't want to be too specific since your question is a bit broad ; this code may or may not help you depending on your use case. But that's generally how you slow down time without affecting system time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM