C# - Number Of Cores and Processors

27. October 2011 13:55

 

If your working with threads in c# is can be useful to be able to find out the number of processors and the total number of cores avilable to an application so that you can adjust the maximum number of threads to a sensible value when an application starts. After all there is no point in attempting to execute 100 high processor intensive task's in a system with only 2 cores. It will just grind your application and possibly windows to a complete halt.

 

Heres is some code to find that information out

 

public static class ThreadSystemInfo
{
	private static bool HasData = false;

	private static void Init()
	{
		if (HasData)
			return;

		ObjectQuery wql = new ObjectQuery("SELECT * FROM Win32_Processor");
		ManagementObjectSearcher searcher = new ManagementObjectSearcher(wql);
		ManagementObjectCollection results = searcher.Get();

		foreach(ManagementObject result in results) {
			_NumberOfCores = int.Parse(result["NumberOfCores"].ToString());
			_NumberOfLogicalProcessors = int.Parse(result["NumberOfLogicalProcessors"].ToString());
			break;
		}

		HasData = true;
	}

	private static int _NumberOfCores = 0;
	public static int NumberOfCores
	{
		get
		{
			Init();
			return _NumberOfCores;
		}
	}

	private static int _NumberOfLogicalProcessors = 0;
	public static int NumberOfLogicalProcessors
	{
		get
		{
			Init();
			return _NumberOfLogicalProcessors;
		}
	}
}

E-mail Kick it! DZone it! del.icio.us Permalink


Windows 7 - RealTek PCIe Network Card

24. October 2011 12:58

 

It looks like the standard driver that shipped with windows 7 for the Realtek PCIe network card is somewhat buggy. It seems to trigger disconnects under load from the switch. However when you look at the details of the connection from the switch end of the connection there will be little or no errors. Only the disconnects will be logged.

 

It seems to be happening with the driver version 7.00.xx.xx but seems to be corrected after updating to version 7.046. More instrcutions for the update at the bottom.

 

You can see this below ...

 

 

FastEthernet0 is up, line protocol is up
  Hardware is Fast Ethernet, address is 001e.1366.750d (bia 001e.1366.750d)
  MTU 1500 bytes, BW 100000 Kbit/sec, DLY 100 usec,
     reliability 255/255, txload 18/255, rxload 142/255
  Encapsulation ARPA, loopback not set
  Keepalive set (10 sec)
  Full-duplex, 100Mb/s
  ARP type: ARPA, ARP Timeout 04:00:00
  Last input never, output never, output hang never
  Last clearing of "show interface" counters never
  Input queue: 0/75/0/0 (size/max/drops/flushes); Total output drops: 129
  Queueing strategy: fifo
  Output queue: 0/40 (size/max)
  5 minute input rate 55719000 bits/sec, 4977 packets/sec
  5 minute output rate 7307000 bits/sec, 3592 packets/sec
     288342812 packets input, 1052441307 bytes, 0 no buffer
     Received 17829 broadcasts, 0 runts, 321 giants, 0 throttles
     0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored
     0 input packets with dribble condition detected
     365975051 packets output, 3739658513 bytes, 0 underruns
     0 output errors, 0 collisions, 2 interface resets
     0 unknown protocol drops
     0 babbles, 0 late collision, 0 deferred
     0 lost carrier, 0 no carrier
     0 output buffer failures, 0 output buffers swapped out

 

However if the connection is placed under significant load in window 7 then the following will begine to occur ...

 

 

Oct 22 11:29:45: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to down
Oct 22 11:29:46: %LINK-3-UPDOWN: Interface FastEthernet0, changed state to up
Oct 22 11:29:47: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to up
Oct 22 11:29:59: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to down
Oct 22 11:30:00: %LINK-3-UPDOWN: Interface FastEthernet0, changed state to up
Oct 22 11:30:01: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to up
Oct 22 11:30:09: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to down
Oct 22 11:30:10: %LINK-3-UPDOWN: Interface FastEthernet0, changed state to up
Oct 22 11:30:11: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to up
Oct 22 11:30:23: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to down
Oct 22 11:30:24: %LINK-3-UPDOWN: Interface FastEthernet0, changed state to up
Oct 22 11:30:25: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to up
Oct 22 11:30:33: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to down
Oct 22 11:30:34: %LINK-3-UPDOWN: Interface FastEthernet0, changed state to up
Oct 22 11:30:35: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to up
Oct 22 11:30:57: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to down
Oct 22 11:30:58: %LINK-3-UPDOWN: Interface FastEthernet0, changed state to up
Oct 22 11:30:59: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to up
Oct 22 11:31:21: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to down
Oct 22 11:31:22: %LINK-3-UPDOWN: Interface FastEthernet0, changed state to up
Oct 22 11:31:23: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to up
Oct 22 11:31:33: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to down
Oct 22 11:31:34: %LINK-3-UPDOWN: Interface FastEthernet0, changed state to up
Oct 22 11:31:35: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0, changed state to up

 

 

Which probably isn't the best thing when attempting to use a network drive. In this case the connection would not be able to cope a medium sized file (300mb) to a server before the connection would reset. However the card would function correctly for web browsing or lighter load.

 

The driver is next to impossible to find on the internet but the following will work.

 

to get to the screen below right click on "Computer" that is located in the start button and select manage. Locate the Device manage and find the Realtek PCIe card.

 

 

If the version is lower than 7.46.610 then you should update. Windows will do this for you automatically once you click the update driver button.

 

E-mail Kick it! DZone it! del.icio.us Permalink


Want To Learn To Program?

22. October 2011 12:09

It seems that time of year has come again where lots of people (mostly students) want to bombard forums with “What language should I learn?” “How do I learn to program?” and various other questions about starting out as a programmer.

 

Something that seems to be extremely common about this is that each person asking the question seems to think that there individual situation is uniquely different to anyone else trying to learn to program. Normally they include some background but never a direction that they want to move in.

 

The background is normally made up of “I can use a computer”. Which is great in many ways however many people can also use a computer so how is your situation different?. What you should be asking is how can I learn to “write a web application”, “how to write a windows application”. Or better yet  how should I solve a particular problem.

If you want to learn to program. You should have a goal. Programming is about using a tool to solve a problem. If you have no problem to solve then you don’t have anything to program. This makes it rather difficult to start. Or ask you’re self which tool should you get from the DIY store when you have not planned or thought about doing any DIY!

 

So how can somebody get started?


The first most important point that somebody needs to know before trying to pick their language of choice to learn is that you need to know what you want to do first. If you don’t have a specific problem you need to create one. It will also need to be achievable. If you want to write computer games start with something like “brickout” instead of “counter strike” for example. Since the first can be done by a single person with no programming experience in a number of weeks the 2nd requires a significant amount of man power in the order of 1 million hours for an individual from scratch.

 

So you cannot think of a problem?


If you are unable to come up with your own problem to solve and you still want to learn to program that pick a problem from “off the shelf”. Even if the problem has been solved before it is probably worth your while to go and solve the problem in your own way. It will give you something to aim for.

 

There must be an easy way to start?


There really isn’t. Just like any other trade it is difficult to learn to start out in. Probably the most simple way to get started is to keep things really basic. If you have still not picked a language that you want to learn in then select a number of languages that you cannot decide between and try to setup and learn the environment. I would suggest writing a basic console based application on a simple problem this is what the “hello, world” application is for.

It is actually worth your while to do. If you write the “hello, world” application in several different languages it will give you a basic test for the environment you will be learning in. If you found it really hard to get it to run compared to another environment then you should probably pick the easier environment as it is the path of least resistance.

If you find “hello, world” is not a difficult enough task try writing a more complex task in each language again. You should probably repeat this 2-3 times and you will probably have a clear winner to which environment you will be learning it.

 You should also be aware that almost all modern languages are based around the same principles. They each encourage you to break up code into “manageable” chunks. They all support the same control flow with loops / case / if’s / functions / basic variable types (for storing data). Code management in programming is actually half the battle when things get start to get really complex.

The skills learnt in one language are almost directly transferable to any other modern language. Take an example of php vs sap.net.  Both languages / environments are meant to make web sites. They both solve the same problem. Both have the same goal. Both are very different in how things are named however they both still have an overlapping skill set. Typically all the modern languages solve all the basic problems that you will come across in your first year. Or there will be a solution available somewhere.

 

The most important thing I should probably mention is that the online communities have people who will help each other. If you ask open ended questions which are not specific you will get poor responses or questions back. If you ask smart well researched questions (showing several attempts) you will get much more useful responses.

In short anyone asking “I want to learn to program? What language should I learn?” Should always be met with the direct response of what are you trying to make / build / solve? Anything other response is probably either biased or shaky at best.

 

The Best Tip?


Programming is about breaking a problem up into smaller parts then managing the problem. This is a basic principle. If you cannot break a problem into managable parts then it does not matter which programming language or enviroment you work with you will almost always end up with a big bag of mess in front of you.

E-mail Kick it! DZone it! del.icio.us Permalink


Want To Learn To Program?

22. October 2011 12:09

 

Want to learn to program?

It seems that time of year has come again where lots of people (mostly students) want to bombard forums with “What language should I learn?” “How do I learn to program?” and various other questions about starting out as a programmer.

 

Something that seems to be extremely common about this is that each person asking the question seems to think that there individual situation is uniquely different to anyone else trying to learn to program. Normally they include some background but never a direction that they want to move in.

 

The background is normally made up of “I can use a computer”. Which is great in many ways however many people can also use a computer so how is your situation different?. What you should be asking is how can I learn to “write a web application”, “how to write a windows application”. Or better yet  how should I solve a particular problem.

If you want to learn to program. You should have a goal. Programming is about using a tool to solve a problem. If you have no problem to solve then you don’t have anything to program. This makes it rather difficult to start. Or ask you’re self which tool should you get from the DIY store when you have not planned or thought about doing any DIY!

 

So how can somebody get started?


The first most important point that somebody needs to know before trying to pick their language of choice to learn is that you need to know what you want to do first. If you don’t have a specific problem you need to create one. It will also need to be achievable. If you want to write computer games start with something like “brickout” instead of “counter strike” for example. Since the first can be done by a single person with no programming experience in a number of weeks the 2nd requires a significant amount of man power in the order of 1 million hours for an individual from scratch.

 

So you cannot think of a problem?

If you are unable to come up with your own problem to solve and you still want to learn to program that pick a problem from “off the shelf”. Even if the problem has been solved before it is probably worth your while to go and solve the problem in your own way. It will give you something to aim for.

 

There must be an easy way to start?


There really isn’t. Just like any other trade it is difficult to learn to start out in. Probably the most simple way to get started is to keep things really basic. If you have still not picked a language that you want to learn in then select a number of languages that you cannot decide between and try to setup and learn the environment. I would suggest writing a basic console based application on a simple problem this is what the “hello, world” application is for.

 

It is actually worth your while to do. If you write the “hello, world” application in several different languages it will give you a basic test for the environment you will be learning in. If you found it really hard to get it to run compared to another environment then you should probably pick the easier environment as it is the path of least resistance.

 

If you find “hello, world” is not a difficult enough task try writing a more complex task in each language again. You should probably repeat this 2-3 times and you will probably have a clear winner to which environment you will be learning it.

 

 You should also be aware that almost all modern languages are based around the same principles. They each encourage you to break up code into “manageable” chunks. They all support the same control flow with loops / case / if’s / functions / basic variable types (for storing data). Code management in programming is actually half the battle when things get start to get really complex.

 

The skills learnt in one language are almost directly transferable to any other modern language. Take an example of php vs sap.net.  Both languages / environments are meant to make web sites. They both solve the same problem. Both have the same goal. Both are very different in how things are named however they both still have an overlapping skill set. Typically all the modern languages solve all the basic problems that you will come across in your first year. Or there will be a solution available somewhere.

 

The most important thing I should probably mention is that the online communities have people who will help each other. If you ask open ended questions which are not specific you will get poor responses or questions back. If you ask smart well researched questions (showing several attempts) you will get much more useful responses.

 

In short anyone asking “I want to learn to program? What language should I learn?” Should always be met with the direct response of what are you trying to make / build / solve?

E-mail Kick it! DZone it! del.icio.us Permalink


C# - ThreadPooled

22. October 2011 10:34

 

This is another example in a series of posts for working with thread in c#. In this example it shows how to create a custom thread pool. If you know anything about working with threads in c# you will know that it already has a thread pool. However the existing thread pool is typically in flexible when attempting to write more complex systems.

 

The existing has support for a single queue which is executed on a first in first out bases (fifo). This has a poor limit as it make it impossible to balance the load between tasks. An example would be backgrounding a lot of releatively unimportant taks then not being able to execute a high priority task as quickly as possible in the standard thread pool. It would also not permit the programmer to be able to balance task's. In that case of having a maximum number of threads (eg 5) for task X and a larger number of tasks (eg 20) for task Y.

 

Another approach to solving the above problem would be to use a priority queue. I will write about these in some later posts.

 

I did a previous example on how to create a basic thread queue. I would suggest that you read and understand it before trying to understand the following. Of course the basic queue will only execute one background task at a time. this example will execute many concurrent items at a time.

 

The basic variables we have in our class are almost the same as the basic queue. The only difference being that we needto clean up older threads when they are not being used. So I added a variable LastKilled to mark the time a spare thread exited because it didn't have any work. So we have the current variables.

 

 

private Queue<IRunnable> Q = new Queue<IRunnable>();
private DateTime LastKilled = DateTime.UtcNow;

 

Since we are a queue we need to be able to accept new items onto the thread. So we have almost the same Add method to add task's to our queue. The major difference being here is that if we do not have a spare thread or any active thread we will start a new thread so long as we are below our maximum number of permitted threads.

 

 

public void Add(IRunnable obj)
{
	lock (Q)
	{
		if (Q.Count > MaxItems)
			throw (new Exception("Too Many Items have been queued"));

		Q.Enqueue(obj);

		/* Mayby Start a new thread? */
		if (CurrentRunning >= CurrentThreads && CurrentThreads < MaxThreads)
		{
			ThreadSimpleRun tmp = new ThreadSimpleRun(this);
			tmp.Start();
			_CurrentThreads++;
		}

		Monitor.Pulse(Q);
	}
}

 

The part of code that changes significatly compared to the basic queue example is how item's are dequeued. Every time we start a new thread it will be executing on the following function. The Run function is used to take an item off the queue and execute it in the background. When there is no work to be done it will also sleep until a task is added to the queue and it is told to "wakeup" from the Add method above. At the same time the thread will sleep for a maximum time then "wakeup" if a significant period of time has passed with no work then it will exit to save on resources.

 

 

public void Run()
{
	while (true)
	{
		try
		{
			IRunnable item = null;

			lock (Q)
			{
				if (Q.Count == 0)
					Monitor.Wait(Q, ShrinkTime);

				if (Q.Count > 0)
				{
					item = Q.Dequeue();
					_CurrentRunning++;
				}
				else
				{
					if (LastKilled.AddMilliseconds(ShrinkTime) > DateTime.UtcNow)
					{
						_CurrentThreads--;
						return;
					}
				}
			}

			if (item == null)
				continue;	//Restart the loop

			item.Run();

			lock (Q)
			{
				_CurrentRunning--;
			}
		}
		catch (Exception ex)
		{
			throw (ex);
		}
	}
}

 

It is probably worth pointing out that we keep a count on the numbers of current executing threads and the total number of background threads. This is so the add function can decide when to create a new thread.

There is also an issue of error handling to be addressed. In this case we leave the error handling to be decided on in the "task". If an exception is passed back into the run function the exepected functionality is to crash. It is left in this way as only the queued tasks will know how to deal with their own error's.

I have left a small deliberate mistake in the code above. It will still function correctly but there is still a slight room for improvment. I wonder if anyone would be able to spot it?

 

Here is a copy of the complete class. Now you can create as many thread pools in c# as you require.

 

 

public class ThreadPooled : IRunnable
{
	private Queue<IRunnable> Q = new Queue<IRunnable>();
	private DateTime LastKilled = DateTime.UtcNow;

	public ThreadPooled()
	{

	}

	public void Add(IRunnable obj)
	{
		lock (Q)
		{
			if (Q.Count > MaxItems)
				throw (new Exception("Too Many Items have been queued"));

			Q.Enqueue(obj);

			/* Mayby Start a new thread? */
			if (CurrentRunning >= CurrentThreads && CurrentThreads < MaxThreads)
			{
				ThreadSimpleRun tmp = new ThreadSimpleRun(this);
				tmp.Start();
				_CurrentThreads++;
			}

			Monitor.Pulse(Q);
		}
	}

	public void Run()
	{
		while (true)
		{
			try
			{
				IRunnable item = null;

				lock (Q)
				{
					if (Q.Count == 0)
						Monitor.Wait(Q, ShrinkTime);

					if (Q.Count > 0)
					{
						item = Q.Dequeue();
						_CurrentRunning++;
					}
					else
					{
						if (LastKilled.AddMilliseconds(ShrinkTime) > DateTime.UtcNow)
						{
							_CurrentThreads--;
							return;
						}
					}
				}

				if (item == null)
					continue;	//Restart the loop

				item.Run();

				lock (Q)
				{
					_CurrentRunning--;
				}
			}
			catch (Exception ex)
			{
				throw (ex);
			}
		}
	}

	public int QueueLength
	{
		get
		{
			lock (Q)
			{
				return Q.Count;
			}
		}
	}

	private int _MaxItems = int.MaxValue;
	public int MaxItems
	{
		get
		{
			return _MaxItems;
		}
		set
		{
			lock (Q)
			{
				if (QueueLength > _MaxItems)
					throw (new Exception("Cannot shrink queue because it already contains more than MaxItems"));
				_MaxItems = value;
			}
		}
	}

	private int _MinThreads = 0;
	public int MinThreads
	{
		get
		{
			return _MinThreads;
		}
		set
		{
			_MinThreads = value;
		}
	}

	private int _CurrentRunning = 0;
	public int CurrentRunning
	{
		get
		{
			return _CurrentRunning;
		}
		set
		{
			_CurrentRunning = value;
		}
	}

	private int _CurrentThreads = 0;
	public int CurrentThreads
	{
		get
		{
			return _CurrentThreads;
		}
	}

	private int _MaxThreads = int.MaxValue;
	public int MaxThreads
	{
		get
		{
			return _MaxThreads;
		}
		set
		{
			_MaxThreads = value;
		}
	}

	private int _ShrinkTime = 60000;
	public int ShrinkTime
	{
		get
		{
			return _ShrinkTime;
		}
		set
		{
			_ShrinkTime = value;
		}
	}
}

 

E-mail Kick it! DZone it! del.icio.us Permalink