6

I have a multithreaded C# application, where the core logic sits in a Timer.Elapsed event handler. The event handler contains 2 for loops which executes a maximum of n * n = 5 * 5 = 25 times.

The application performs well on my PC. I ran VS 2010 Profiler against the application and CPU usage averages at 20%.

The company tester says that on his PC this jumps to between 50% and 100% on his PC. This is causing a performance issues for him.

  • Is there anything i can do to remedy this?
  • What does high CPU usage really mean?
  • Could this be impacting his PC?
  • Is it possible to tell an application to utilize only X amount of the CPU?

Any help would be appreciated.

Dan
  • 2,625
  • 7
  • 39
  • 52
c0D3l0g1c
  • 3,020
  • 5
  • 33
  • 71
  • The number of times the loop executes only means something in context to what it executes. If you execute expensive operation 25 times that could be a large issue. If you are summing to 25 it won't matter. – rerun Nov 08 '10 at 09:31
  • How often is your timer firing? And do you wait for the operation to complete before you start the timer again, or do you just keep kicking off your loops again and again regardless of whether the previous one has finished? – Dan Puzey Nov 08 '10 at 14:37
  • Timer executes every second. In the timer event handler, i stop the timer in the first line of code and re-start it in the last line of code. Effectively, this just creates a 1 second delay between events. The code between starting and stopping the timer, does some calculations in memory on a ConcurrentDictionary, which can grow quite substantially. The calculations are quite simple but are based on large amounts of data. No interaction with UI happens in this event handler, hence i am not using a DispatcherTimer nor a BackgroundWorker. The ConcurrentDictionary is updated by various events. – c0D3l0g1c Nov 09 '10 at 05:59
  • I originally had this code in a thread, which had a while loop, looping over a loop control variable, i.e. while(variable) { //Some Code }. This approach was less efficient as it used up more resources. Hence i switched to a timer, which reduced CPU utilisation. – c0D3l0g1c Nov 09 '10 at 06:01

5 Answers5

7
  • run the timer event less frequently
  • do the work on a worker thread (so the UI is at least responsive)
  • do less work in the timer (or do it more efficiently)
  • get more CPU

I'm guessing you really mean the third bullet, but we can't answer that without knowing what the code is doing; but (random suggestions without any context):

  • look at any collection access to see if there is a place for a dictionary, hash-set, or similar
  • check if you are doing vast amounts of IO (in particular to a DB) which could be reduced
  • check if you are going lots of thread-switches via Invoke (or the UI's equivalent)
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
3

You're in wondering and guessing mode. Forget CPU percent. What pros do is find out why the program's spending time and if it's necessary.

What you could do is just run that code flat out in a long loop, and sample it. I use this method. Stack samples will land preferentially in the heavy branches of the call tree. Chances are you can lop off some of those heavy branches and get a nice speedup.

Community
  • 1
  • 1
Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
  • @c0D3l0g1c: Here's the thing about CPU Usage. The CPU is always executing. When it's not executing real code, it's executing the idle process. Usage is just a short-term running average of time spent in real code. While your process waits for I/O, it's not running, so that shows up as lower usage. If it's crunching, it's higher. It has little to do with efficiency of the code. The thing to do is what I said. Basically, get the lead out, by finding heavy branches of the call tree that you can prune off. – Mike Dunlavey Nov 09 '10 at 12:40
  • Thanks, makes sense! Your article from a previous post is useful. – c0D3l0g1c Nov 10 '10 at 04:22
  • @c0D3l0g1c: You're welcome, and spread the word. Performance tuning is *easy*. Finding bugs is hard, because you have to trace along until the program does something wrong. But to find "bottlenecks", basically, you just pause it (a few times) and see what it's doing. – Mike Dunlavey Nov 10 '10 at 13:31
1

just add the Thread.Sleep(1); inside your for loop. this stabilize the CPU usage and restrict from using CPU at Maximum speed.

1

May be your application runs multiple threads. I have same issue that runs multiple threads and in each thread there is continuous update which makes the application usage from 50% to 100%.

After investigating the issue, I have just introduced the delay in continuous loop of the thread (Thread(100)). This brings the application usage back to 1% to 3%.

Hassan Rahman
  • 4,953
  • 1
  • 34
  • 32
1

Add Thread.Sleep(int); in the code to reduce cpu time. even just 30 milliseconds can save the juice of the processor.

Nav E
  • 11
  • 3