1

I have a program that loads System's Event logs to a Hastable to be used. The problem is that it's utilizing 100% of the CPU. What is the best solution to lower the usage using API calls.

Hashtable currentLog = (Hashtable)_logs[l.Log];

foreach (EventLogEntry e in l.Entries)
{    
    if (_lastRun <= e.TimeWritten.ToUniversalTime() )
    {                                
        if (_verboseOutput)
        {
            Logger.TraceWrite(String.Format(
                                    "Source={0}, EventId={1}, Date/Time={2}, Message={3}", 
                                     e.Source, 
                                     e.EventID, 
                                     e.TimeWritten, 
                                     e.Message));
        }

        string key = GetEventKey(e);
        if (currentLog[key] == null)
        {
            currentLog[key] = e;
        }
    }
}
sll
  • 61,540
  • 22
  • 104
  • 156
Rawanee
  • 11
  • 2
  • When you say "100% CPU", do you actually mean "100% **core**"? In either case, why is this a problem? Did you actually want to say that it takes a long time? If so, how much time? – Branko Dimitrijevic Oct 05 '11 at 10:36
  • 100% CPU. Is it healthy when an event utilizes 100% of the CPU? – Rawanee Oct 05 '11 at 10:58
  • For the **exact same** amount of processing, it is "healthy" to have 100% versus, say, 50% usage, because this means you'll finish twice as fast. What I don't quite see is how can you get the 100% CPU usage from the above piece of code unless you are on a single-core CPU. On my quad-core, I get only 25% CPU usage (i.e. 100% core usage), for the simplified version of the above code. Perhaps `Logger.TraceWrite` is passing data to a background thread (could you show us that)? – Branko Dimitrijevic Oct 05 '11 at 12:25
  • Actually I am on a single core CPU, but this is not the whole code just a small part of it. This is what's happening in the Logger.TraceWrite, public static void TraceWrite( string msg, string application ) { Trace.WriteLine(String.Format("[{0}]: {1}", application, msg)); } public static void TraceWrite( string msg ) { Logger.TraceWrite( msg, Application ); } – Rawanee Oct 05 '11 at 12:33

4 Answers4

0

You can load logs in a separate thread with low priority (Thread.Priority):

Thread thread = new Thread(loadLogsMethod);
thread.Priority = ThreadPriority.BelowNormal;
thread.Start();

EDIT: By delegating execution to a separate thread you decrease average CPU load but total execution time will be increased.

sll
  • 61,540
  • 22
  • 104
  • 156
  • 1
    This won't use up less CPU cycles, it'll just defer execution to threads with a higher priority. It may improve system stability a little, but it doesn't solve the problem. – Polynomial Oct 05 '11 at 10:12
  • @Polynomial : I believe in this way (thread prioritizing) CPU *load* will be decreased (but total execution time will be increased). – sll Oct 05 '11 at 10:18
  • Nope, the overall CPU load will be the same. It just allows other threads of higher priority to jump in and execute on the processor instead of your thread. – Polynomial Oct 05 '11 at 10:20
  • @Polynomial : right, and peak load will be decreased. Try out to launch heavy loop in main thread, then run the same loop in a separate low-priority thread – sll Oct 05 '11 at 10:22
  • Just tested it, I still hit 100% CPU over four cores. The system is more responsive with the thread priority low, though. It'll drop if you're running XP, but that's because the thread scheduler leaks a small portion of thread execution quantums that aren't fully utilised. In Vista and later, the tails ends of those quantums are pre-empted and utilised. – Polynomial Oct 05 '11 at 10:44
0

It seems that before you go ahead and change your code it would be wise to perform some performance testing to see where the bottlenecks lie.

A question I asked a few months ago talks about the methods you can use to measure the performance of your application, as well as some of the considerations that you can make whilst doing so:

Function profiling woes - Visual Studio 2010 Ultimate

Community
  • 1
  • 1
Jamie Keeling
  • 9,806
  • 17
  • 65
  • 102
0

Usually, there is nothing wrong with 100% CPU use1. All that means is that the processor is running at maximum for the duration of the operation. This is a good thing. Why waste time forcing the CPU to stop working? The OS is most likely a pre-emptive OS (since you've tagged c# it's likely to be Windows), so Polynomial's comment about stability is incorrect, the OS will switch tasks regardless of the load.

If you reduce the CPU use to 50% then the processing will take twice as long.

What you want to ask is "How can I reduce the time this algorithm takes" / "Is there a more efficient algorithm" since any algorithm you use will run at 100% until it completes.

It would help if you explain what you're trying to do here, perhaps there's a better way to do it.

Looking at the code, I think the biggest overhead is in the GetEventKey method, showing us that code may help.

  1. 100% CPU usage in a GUI thread is generally a bad thing as the GUI could become unusable as the GUI thread has to wait until the method that's consuming the CPU finishes before handling user interaction.
Skizz
  • 69,698
  • 10
  • 71
  • 108
-1

The high CPU usage is probably due to the iterator having to walk the entire event log to check if there any new ones available. Try switching the foreach out and using a for instead. You can also try using the performance analysis tools in Visual Studio to see which line(s) are CPU hotspots.

Polynomial
  • 27,674
  • 12
  • 80
  • 107
  • Is there a way to reduce the CPU utilization by using API calls? Since the for is not giving noticed changes as per CPU utilization. – Rawanee Oct 05 '11 at 10:32