I've been attempting to understand how long it takes to "wake" a thread who is waiting on a blocking construct like AutoResetEvent- from what I understood after reading multiple discussions is that windows has some kind of internal clock which "ticks" every 15.6ms (or so) and then decide which threads are scheduled to run next, so I would expect that the time difference between signaling a thread until that thread wakes up would take a random time between 0-15.6ms.
So I wrote this small program to test my theory:
static void Main(string[] args)
{
double total = 0;
int max = 100;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < max; i++)
{
AutoResetEvent eventHandle = new AutoResetEvent(false);
double time1 = 0;
double time2 = 0;
Thread t1 = new Thread(new ThreadStart(() => time1 = f1(stopwatch, eventHandle)));
Thread t2 = new Thread(new ThreadStart(() => time2 = f2(stopwatch, eventHandle)));
t1.Start();
t2.Start();
t1.Join();
t2.Join();
double diff = time2 - time1;
total += diff;
Console.WriteLine("Diff = " + diff.ToString("F4"));
}
double avg = total / max;
Console.WriteLine("Avg = " + avg.ToString("F4"));
Console.ReadKey();
}
static double f1(Stopwatch s, AutoResetEvent eventHandle)
{
Thread.Sleep(500);
double res = s.Elapsed.TotalMilliseconds;
eventHandle.Set();
return res;
}
static double f2(Stopwatch s, AutoResetEvent eventHandle)
{
eventHandle.WaitOne();
return s.Elapsed.TotalMilliseconds;
}
To my surprise the average wake-up time was around 0.05 milliseconds - so obviously i'm missing something but I don't know what...
No, 15.625 msec is the period of the clock tick interrupt. Which lets the scheduler interrupt a thread if it has been running without blocking and the scheduler decides that another thread should get a turn.
Threads that block will be pre-empted at their WaitXxx() call. Or Sleep() call. Regardless of the clock tick interrupt.
Notable as well is that a sleeping thread can only resume running at a clock interrupt tick, the reason that Thread.Sleep(1) in fact sleeps for 15.6 msec. Timers, DateTime.Now and Environment.TickCount also have that accuracy, the clock is incremented by the interrupt.
Related
I am performing some heavy load Tasks on my application. For that, I want to calculate the CPU load during that operation, minimum and maximum CPU utilization. I am using Process namespace. The problem is that for every process I am getting the same value for maximum and minimum. 1.79769313486232E+308
Here is my code:
private async Task<double> GetCpuLoadAsync(TimeSpan measurementWindow)
{
Process CurrentProcess = Process.GetCurrentProcess();
TimeSpan StartCpuTime = CurrentProcess.TotalProcessorTime;
Stopwatch Timer = Stopwatch.StartNew();
await Task.Delay(measurementWindow);
TimeSpan EndCpuTime = CurrentProcess.TotalProcessorTime;
Timer.Stop();
return (EndCpuTime - StartCpuTime).TotalMilliseconds / (Environment.ProcessorCount * Timer.ElapsedMilliseconds);
}
and I am calling this function on a timer and starting the timer before getting into that method:
double maxCpu = double.MinValue, minCpu = double.MaxValue;
elapsedTimer.Elapsed += new ElapsedEventHandler(async (s, e) =>
{
double cpuUsage = await GetCpuLoadAsync(TimeSpan.FromMilliseconds(1000));
if (cpuUsage > maxCpu)
{
maxCpu = cpuUsage;
}
if(cpuUsage < minCpu)
{
minCpu = cpuUsage;
}
});
// Here I am calling my method. It takes 3-4 mins to process and I want to calculate CPU usage during that time.
elapsedTimer.stop();
In C# I have an example:
public async static Task TaskTest(int i)
{
await Task.Delay(1);
Console.WriteLine($"{i}. {DateTime.Now.ToString("HH:mm:ss fff")} " +
$"ThreadId:{Thread.CurrentThread.ManagedThreadId} Start");
int count = 1;
while (true)
{
DoSomeThing(count);
var stopWatch = new Stopwatch();
stopWatch.Start();
await Task.Delay(100);
stopWatch.Stop();
if (stopWatch.Elapsed.TotalMilliseconds > 200)
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Id:{count} Time:{DateTime.Now.ToString("HH:mm:ss fff")} " +
$"ThreadID:{Thread.CurrentThread.ManagedThreadId} Time Delay:{stopWatch.Elapsed.TotalMilliseconds }");
Console.ForegroundColor = ConsoleColor.White;
count++;
}
}
public async static Task DoSomeThing(int index)
{
await Task.Delay(1);
Task.Delay(1000).Wait();
}
private static void Main(string[] args)
{
int i = 1;
while (i < 2)
{
TaskTest(i);
Task.Delay(1).Wait();
i++;
}
Console.ReadKey();
}
Here is my result
Result
Id:8 Time:23:03:59 972 ThreadID:12 Time Delay:582.6348
Id:22 Time:23:04:01 974 ThreadID:14 Time Delay:552.7234000000001
Id:42 Time:23:04:04 967 ThreadID:8 Time Delay:907.3214
I don't know why Task sometimes delay more than 200 milliseconds.
Update:
Thank for all answer.
I update my code to use Thread and Thread.Sleep() and Task.Run(). I increase number of Threads run forever to 500. I tested in 30 minutes and 500 threads never sleep more than 200ms.
Do you think that is bad code?
Please leave a comment!
Thank you so much!
public static void TaskTest(object i)
{
Console.WriteLine($"{i} Start");
int count = 1;
while (true)
{
// Open Task to do work
Task.Run(() => { DoSomeThing(count); });
var stopWatch = new Stopwatch();
stopWatch.Start();
Thread.Sleep(100);
stopWatch.Stop();
if (stopWatch.Elapsed.TotalMilliseconds > 200)
{
Console.WriteLine($"Id:{count} Time:{DateTime.Now.ToString("HH:mm:ss fff")} " +
$"ThreadID:{Thread.CurrentThread.ManagedThreadId} Time Delay:{stopWatch.Elapsed.TotalMilliseconds }");
}
count++;
}
}
public static void DoSomeThing(int index)
{
Thread.Sleep(1000); // Time spent complete work
}
private static void Main(string[] args)
{
int i = 0;
while (i < 500)
{
// Open Thread for TaskTest
Thread tesThread = new Thread(TaskTest);
tesThread.IsBackground = true;
tesThread.Start(i);
i++;
}
Console.WriteLine("Finish init");
Console.ReadKey();
}
Task.Delay, like any other multi-threaded sleep function, yields the thread it's running on back to the system (or in the case of the thread pool, back to the thread pool scheduler), asking to be re-scheduled some time after the amount of time specified.
That is the only guarantee you have, that it will wait at least the amount specified. How long it will actually wait heavily depends on your thread pool load (you're delaying an awful lot of tasks there), general system load (there's thousands of threads at any given point in time to be scheduled on an average computer OS) and on your CPU&OS's capability to schedule threads quickly (in Windows, look at timeBeginPeriod).
Long story short, if precise timing matters to you, don't relinquish your thread.
I am trying to refresh my frame every 17ms with a timer.
Timer timer = new Timer(17);
timer.Elapsed += ResetFrame;
timer.Start();
But instead of waiting for 17ms and then repeating, it waited for the frame refresh to complete and then wait for 17msfor the next repeat. This causes the frame to be refreshed every 28ms. How to synchronize it with real time?
To have a real time timer having a very short interval, you can take a look at this article:
Real Time Timer in C#
In Dot Net, following timers are not real time.
System.Windows.Forms.Timer
System.Timers.Timer
System.Threading.Timer
Means if you want to run your code at every 100 millisecond then above
timer fire even around 110 millisecond or later. Windows is not a real
time OS because of this .Net is also not a real time.
To create a real time timer in C# you have to write custom code that
can hold CPU to run your code at right time.
class Program
{
static void Main(string[] args)
{
Console.ReadLine();
Console.WriteLine("Running");
RealTimeTimerTest obj = new RealTimeTimerTest();
obj.Run();
}
}
public class RealTimeTimerTest
{
List<DateTime> lst = new List<DateTime>();
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
public void Run()
{
int Tick = 100;
int Sleep = Tick - 20;
long OldElapsedMilliseconds = 0;
sw.Start();
while (sw.IsRunning)
{
long ElapsedMilliseconds = sw.ElapsedMilliseconds;
long mod = (ElapsedMilliseconds % Tick);
if (OldElapsedMilliseconds != ElapsedMilliseconds && (mod == 0 || ElapsedMilliseconds > Tick))
{
//-----------------Do here whatever you want to do--------------Start
lst.Add(DateTime.Now);
//-----------------Do here whatever you want to do--------------End
//-----------------Restart----------------Start
OldElapsedMilliseconds = ElapsedMilliseconds;
OldElapsedMilliseconds = 0;
sw.Reset();
sw.Start();
System.Threading.Thread.Sleep(Sleep);
//-----------------Restart----------------End
}
//------------Must define some condition to break the loop here-----------Start
if (lst.Count > 500)
{
Write();
break;
}
//-------------Must define some condition to break the loop here-----------End
}
}
private void Write()
{
System.IO.StreamWriter sw = new System.IO.StreamWriter("d:\\text.txt", true);
foreach (DateTime dtStart in lst)
sw.WriteLine(dtStart.ToString("HH:mm:ss.ffffff")); sw.Close();
}
}
Also that:
Most accurate timer in .NET?
High resolution timer
High resolution timer in C#
Microsecond and Millisecond C# Timer
Precision-Repeat-Action-On-Interval-Async-Method
I'm working on windows service and I want to call a method from OnStart every minute. I originally had a forever while loop but then the service wouldn't install.
while (true)
{
Stopwatch stopWatch = new Stopwatch();
int totalTime = 0;
stopWatch.Start();
MethodToCall();
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
totalTime = ts.Seconds * 1000 + ts.Milliseconds;
if (totalTime < 60000)
{
Thread.Sleep(60000 - totalTime);
//ManualResetEvent.WaitOne(10000);
}
else
{
Thread.Sleep(30000);
}
}
So, how can I make my method call every minute BUT when the method exceeds one minute it will wait N number of minutes(let's say 30 seconds) and then start over by calling the method.
Something like this should work. With the AutoReset flag set to false, the timer will only fire once, after the specified interval time. In the finally block, we make sure to restart the timer countdown, waiting for the interval to elapse again.
var interval = TimeSpan.FromMinutes( 1 );
var timer = new System.Timers.Timer( interval.TotalMilliseconds ) { AutoReset = false };
timer.Elapsed += ( sender, eventArgs ) =>
{
var start = DateTime.Now;
try
{
// do work
}
finally
{
var elapsed = DateTime.Now - start;
if ( elapsed < interval )
timer.Interval = (interval - elapsed).TotalMilliseconds;
else
timer.Interval = TimeSpan.FromSeconds( 30 ).TotalMilliseconds;
timer.Start();
}
};
timer.Start();
Source for Timer.Elapsed (note the bit about setting Interval resetting the countdown)
There are two solutions depending on what you want. Do you want to do work once a minute on the minute and always wait for the next minute? Or do you want to run no more than once a minute but it's okay to "catch up" if you fall behind?
In other words, if processing takes 80 seconds then does the next work start immediately or wait until T=120?
The first is easier, but note that I haven't tested this and it's just a guideline:
AutoResetEvent waitHandle = new AutoResetEvent(false);
System.Timer(() => waitHandle.Set(), null, TimeSpan.FromMinutes(1), TimeSpan.FromMilliseconds(-1));
while (true)
{
// Do stuff
waitHandle.WaitOne();
}
The second is just a bit harder.
ManualResetEvent waitHandle = new ManualResetEvent (false);
System.Timer(() => waitHandle.Set(), null, TimeSpan.FromMinutes(1), TimeSpan.FromMilliseconds(-1));
while (true)
{
// Do stuff
waitHandle.Reset();
waitHandle.WaitOne();
}
How could I generate steady CPU load in C#, lower than 100% for a certain time? I would also like to be able to change the load amount after a certain period of time. How do you recommend to generate usage spikes for a very short time?
First off, you have to understand that CPU usage is always an average over a certain time. At any given time, the CPU is either working or it is not. The CPU is never 40% working.
We can, however, simulate a 40% load over say a second by having the CPU work for 0.4 seconds and sleep 0.6 seconds. That gives an average utilization of 40% over that second.
Cutting it down to smaller than one second, say 100 millisecond chunks should give even more stable utilization.
The following method will take an argument that is desired utilization and then utilize a single CPU/core to that degree:
public static void ConsumeCPU(int percentage)
{
if (percentage < 0 || percentage > 100)
throw new ArgumentException("percentage");
Stopwatch watch = new Stopwatch();
watch.Start();
while (true)
{
// Make the loop go on for "percentage" milliseconds then sleep the
// remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms
if (watch.ElapsedMilliseconds > percentage)
{
Thread.Sleep(100 - percentage);
watch.Reset();
watch.Start();
}
}
}
I'm using a stopwatch here because it is more accurate than the the TickCount property, but you could likewise use that and use subtraction to check if you've run long enough.
Two things to keep in mind:
on multi core systems, you will have to spawn one thread for each core. Otherwise, you'll see only one CPU/core being exercised giving roughly "percentage/number-of-cores" utilization.
Thread.Sleep is not very accurate. It will never guarantee times exactly to the millisecond so you will see some variations in your results
To answer your second question, about changing the utilization after a certain time, I suggest you run this method on one or more threads (depending on number of cores) and then when you want to change utilization you just stop those threads and spawn new ones with the new percentage values. That way, you don't have to implement thread communication to change percentage of a running thread.
Just in add of the Isak response, I let here a simple implementation for multicore:
public static void CPUKill(object cpuUsage)
{
Parallel.For(0, 1, new Action<int>((int i) =>
{
Stopwatch watch = new Stopwatch();
watch.Start();
while (true)
{
if (watch.ElapsedMilliseconds > (int)cpuUsage)
{
Thread.Sleep(100 - (int)cpuUsage);
watch.Reset();
watch.Start();
}
}
}));
}
static void Main(string[] args)
{
int cpuUsage = 50;
int time = 10000;
List<Thread> threads = new List<Thread>();
for (int i = 0; i < Environment.ProcessorCount; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(CPUKill));
t.Start(cpuUsage);
threads.Add(t);
}
Thread.Sleep(time);
foreach (var t in threads)
{
t.Abort();
}
}
For a uniform stressing: Isak Savo's answer with a slight tweak. The problem is interesting. In reality there are workloads that far exceed it in terms of wattage used, thermal output, lane saturation, etc. and perhaps the use of a loop as the workload is poor and almost unrealistic.
int percentage = 80;
for (int i = 0; i < Environment.ProcessorCount; i++)
{
(new Thread(() =>
{
Stopwatch watch = new Stopwatch();
watch.Start();
while (true)
{
// Make the loop go on for "percentage" milliseconds then sleep the
// remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms
if (watch.ElapsedMilliseconds > percentage)
{
Thread.Sleep(100 - percentage);
watch.Reset();
watch.Start();
}
}
})).Start();
}
Each time you have to set cpuUsageIncreaseby variable.
for example:
1- Cpu % increase by > cpuUsageIncreaseby % for one minute.
2- Go down to 0% for 20 seconds.
3- Goto step 1.
private void test()
{
int cpuUsageIncreaseby = 10;
while (true)
{
for (int i = 0; i < 4; i++)
{
//Console.WriteLine("am running ");
//DateTime start = DateTime.Now;
int cpuUsage = cpuUsageIncreaseby;
int time = 60000; // duration for cpu must increase for process...
List<Thread> threads = new List<Thread>();
for (int j = 0; j < Environment.ProcessorCount; j++)
{
Thread t = new Thread(new ParameterizedThreadStart(CPUKill));
t.Start(cpuUsage);
threads.Add(t);
}
Thread.Sleep(time);
foreach (var t in threads)
{
t.Abort();
}
//DateTime end = DateTime.Now;
//TimeSpan span = end.Subtract(start);
//Console.WriteLine("Time Difference (seconds): " + span.Seconds);
//Console.WriteLine("10 sec wait... for another.");
cpuUsageIncreaseby = cpuUsageIncreaseby + 10;
System.Threading.Thread.Sleep(20000);
}
}
}