Using dot-trace to analyze high CPU usage application - performance

I have a .NET CORE 3.1 Console application running on a Ubuntu20 x64 server, and randomly experiencing High Cpu(100% for 4 cores) cases.
I'm following diagnostics to start a diag during the peak time for my app likeļ¼š
dotnet-trace collect -p 1039 --providers Microsoft-DotNETCore-SampleProfiler
from the resulted .nettrace file opened in Visual Studio, I can see the Funcions list with CPU Time for each single function.
But I understand the CPU time here is actually the wall time that just means the time of a function call stayed in a thread stack, and no matter it consumes real CPU caculation resource or not.
The hotest spot my this .nettrace now is pointing to these lines of code(pseudo code):
while(true)
{
Thread.Sleep(1000);//<---------hottest spot
socket.Send(bytes);
}
and
while(true)
{
ManualResetEvent.WaitOne();//<---------hottest spot
httpClient.Post(data);
}
Obviously above 2 hottest spot will not consume real CPU resource but just idle waitting, so any way to trace the functions that used the real cpu usage, just like the JetBrains dotTrace provided:

You might want to use external tools like top. This could help to identify the process consuming the CPU percentage.
If your profiler identifies Thread.Sleep() as hottest spot, chances are that your application is waiting for some external process outside the scope of the profiler.

I would suggest refactoring this code to use async and use 'await Task.Wait(xxx)' instead of doing this on the Thread level.
I'm having this suggestion based on partially similar problem which has been described here
Why Thread.Sleep() is so CPU intensive?

Related

Is there a Windows kernel API to get current CPU usage percent, or idle percent?

I ask this question because I'd like to know this from my kernel mode Windows driver.
I have some library code porting from user mode that has some accompanying stress test to run; that stress test code need to know when CPU is idle.
Simple googling shows no result, at least from first several pages.
you need use ZwQuerySystemInformation with SystemProcessorPerformanceInformation infoclass ( you got a array of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION structures on output)

Only 100% shown on benchmark run

I was just doing a 10Million insert benchmark to see the performance of a small cache system I'm building. While observing the Activity Monitor I noticed that the main Go process only shows 100% (of the 800%) CPU.
Do I need to split my loops into routines to make it split up to all 8 cores or is there another reason?
I'm not posting code as the test code is not much more than a loop in a testing function in the main body.
Your application is using only one thread so it's correct that there is only one core that run at 100%.
If you want use more than one core you must use more than one go routine, remeber to set GOMAXPROCS shell enviroment or your application will use only one core.
Remember that it's possible that your application could be even slower using more than one process because if your behaviuor is intrinsically sequential you cannot speed up the application just adding more goroutine. You can take a real advantage of multi threading only if your behaviour is intrinsically parallel.

High CPU Usage with no load

We are running a windows service which every 5 seconds checks a folder for files and if found logs some info about it using NLog.
I already tried the suggestions from ASP.NET: High CPU usage under no load without succes.
When the service was just started there is hardly any CPU usage. After a few hours we see CPU peaks to 100% and after some more waiting the cpu graph looks like:
I tried the steps described in http://blogs.technet.com/b/sooraj-sec/archive/2011/09/14/collecting-data-using-xperf-for-high-cpu-utilization-of-a-process.aspx to produce information on what is going on:
I don't know where to continue. Any help appreciated
Who wrote this windows service? Was it you or 3rd party?
To me, checking folder for changes every 5 seconds sounds really suspicious, and maybe the primary reason why you are getting this massive slowdown.
If you do it right, you can get directory changes immediately as they happen, and yet spend almost no CPU time while doing that.
This Microsoft article explains how exactly to do that: Obtaining Directory Change Notifications by using functions FindFirstChangeNotification, FindNextChangeNotification, ReadDirectoryChangesW and WaitForMultipleObjects.
After a lot of digging it had to do with this:
The service had a private object X with property Y
Every time the service was fired X was passed to the Business Logic. There Y was used and in the end disposed. The garbage collector will then wait until X is disposed, which will never happen until the service is restarted. This caused an extra GC waiting thread every time the service was fired.

Limiting memory of V8 Context

I have a script server that runs arbitrary java script code on our servers. At any given time multiple scripts can be running and I would like to prevent one misbehaving script from eating up all the ram on the machine. I could do this by having each script run in its own process and have an off the shelf monitoring tool monitor the ram usage of each process, killing and restarting the ones that get out of hand. I don't want to do this because I would like to avoid the cost of restart the binary every time one of these scripts goes crazy. Is there a way in v8 to set a per context/isolate memory limit that I can use to sandbox the running scripts?
It should be easy to do now
context.EstimatedSize() to get estimated size of the context
isolate.TerminateExecution() when context goes out of acceptable memory/cpu usage/whatever
in order to get access if there is an infinite loop(or something else blocking, like high cpu calculation) I think you could use isolate.RequestInterrupt()
A single process can run multiple isolates, if you have a 1 isolate to 1 context ratio you can easily
restrict memory usage per isolate
get heap stats
See some examples in this commit:
https://github.com/discourse/mini_racer/commit/f7ec907547e9a6ea888b2587e4edee3766752dd3
In particular you have:
v8::HeapStatistics stats;
isolate->GetHeapStatistics(&stats);
There are also fancy features like memory allocation callbacks you can use.
This is not reliably possible.
All JavaScript contexts by this process share the same object heap.
WebKit/Chromium tries some stuff to disable contexts after context OOMs.
http://code.google.com/searchframe#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/bindings/v8/V8Proxy.cpp&exact_package=chromium&q=V8Proxy&type=cs&l=361
Sources:
http://code.google.com/p/v8/source/browse/trunk/src/heap.h?r=11125&spec=svn11125#280
http://code.google.com/p/chromium/issues/detail?id=40521
http://code.google.com/p/chromium/issues/detail?id=81227

Performance problem with backgroundworkers

I have 15 BackgroundWorers that are running all the time, each one of them works for about half a second (making web request) and none of them is ever stopped.
I've noticed that my program takes about 80% of my computer's processing resources and about 15mb of memory (core 2 duo, 4gb ddr2 memory).
It it normal? web requests are not heavy duty, it just sends and awaits server response, and yes, running 15 of them is really not a pro-performance act (speed was needed) but i didn't think that it would be so intense.
I am new to programming, and i hardly ever (just as any new programmer, I assume) care about performance, but this time it is ridiculous, 80% of processing resources usage for a windows forms application with two listboxes and backgroundworkers making web requests isn't relly what expected.
info:
I use exception handling as part of my routine, which i've once read that isn't really good for performance
I have 15 background workers
My code assures none of them is ever idle
List item
windows forms, visual studio, c#.
------[edit - questions in answers]------
What exactly do you mean by "My code assures none of them is ever idle"?
The program remains waiting
while (bgw1.IsBusy || gbw2.IsBusy ... ... ...) { Application.DoWork();}
then when any of them is free, gets put back to work.
Could you give more details about the workload you're putting this under?
I make an HTTP web request object, open it and wait for the server request. It really has only a couple of lines and does no heavy processing, the half second is due to server awaiting.
In what way, and how many exceptions are being thrown?
When the page doesn't exist, there is a system.WebException, when it works it returns "OK", and about 99% of the pages i check don't exist, so i'd say about 300 exceptions per minute (putting it like this makes it sound creepy, i know, but it works)
If you're running in the debugger, then exceptions are much more expensive than they would be when not debugging
I'm not talking about running it in the debugger, I run the executable, the resulting EXE.
while (bgw1.IsBusy || gbw2.IsBusy ... ... ...) { Application.DoWork();}
What's Application.DoWork(); doing? If it's doing something quickly and returning, this loop alone will consume 100% CPU since it never stops doing something. You can put a sleep(.1) or so inside the loop, to only check the worker threads every so often instead of continuously.
This bit concerns me:
My code assures none of them is ever idle
What exactly do you mean by that?
If you're making thousands and thousands of web requests, and if those requests are returning very quickly, then that could eat some CPU.
Taking 15MB of memory isn't unexpected, but the CPU is the more worrying bit. Could you give more details about the workload you're putting this under? What do you mean by "each one of them workds for about half a second"?
What do you mean by "I use exception handling as part of my routine"? In what way, and how many exceptions are being thrown? If you're running in the debugger, then exceptions are much more expensive than they would be when not debugging - if you're throwing and catching a lot of exceptions, that could be responsible for it...
Run the program in the debugger, pause it ten times, and have a look at the stacktraces. Then you will know what is actually doing when it's busy.
From your text I read that you have a Core 2 Duo. Is that a 2 Threads or a 4 Threads?
If you have a 2 Threads you only should use 2 BackGroundworkers simultaneously.
If you have a 4 Threads then use 4 BGW's simultaneously. If you have more BGW's then use frequently the following statement:
System.Threading.Thread.Sleep(1)
Also use Applications.DOevents.
My general advice is: start simple and slowly make your application more complex.
Have a look at: Visual Basic 2010 Parallel Programming techniques.

Resources