Friday, February 17, 2012

ThreadPool vs Custom Pool : MultiPipeThread


This is actually something I did research on a while back (6 months or so). The ThreadPool object in .NET is a fairly powerful concept which reuses existing threads registered to the pool and allocates new threads as necessary dependent on your machine specs. Like all High Level objects this has some overhead to it, but probably less than what most could create on their own with exactly the same behavior.

But, is all of that truly necessary? My concept was to build a threading system which allocates and starts threads at initialization. It stops them when they're not necessary, but doesn't destroy them. It works with a piping concept system. Basically, in my example I describe 4 pipes associated with the MultiPipeThread object. This object receives information from the 4 threads and handles them appropriately.

Okay, so unlike the .NET ThreadPool, these threads are instantiated in the beginning. They are started immediately and block themselves when their inactive. How do we use them though? Ultimately we create an interface which defines the process method of an item that our threading will handle. Of course this could potentially be a simple delegate, but in my implementation it is not.

When we push items towards the thread piping system, it collections them and places them in a queue. It can potentially be expanded to collection them in buckets to gain more control over order etc. Once there are threads available to accept the information of a given type, if that type is prepared and ready to be added, it pulls the bucket or range of collection matching this type. Adds them all at once. This is where we gain our advantage over the ThreadPool. In the thread pool, every delegate is pushed towards and individual thread, existing or not. In our implementation items are pushed in bulk collections. The thread stays active until that thread pipe is complete. When it is complete it is marked ready for information, and as long as the type this pipe is set to accept is available the process starts over.

Does the tests prove the concept? Well yeah, the concept defines creating something very similar but pushing items in larger collections so there is less thread synchronization. Aside from this they are closely the same object, but we have a lot more control with a custom concept. We know exactly what is being pushed where and have opportunities to control order.


The above diagram shows the classes that are implemented. I know there is little you can see from this vantage point, but these objects are not that complex and easily implemented with some knowledge of synchronizing thread logic in .NET.

My favorite example of this object in use, is like so:

I have different phases of logic that need to be processed, some which can be overlapping some which cannot. Lets say 3 types, 2 of which can overlap and one that cannot. But the one which does not overlap must be first. So we mark it for priority and type ALONE. All pipes are marked to availability to accept ALONE, and we also add types GROUP1 and GROUP2, GROUP1 is allocated to pipes 1 and 2, where GROUP2 is allocated to pipes 3 and 4. Now we push a collection of items containing a mix of all. All objects of type ALONE fill up all 4 pipes immediately. Even though a pipe may open up before completion of ALONE, we restrict groups 1 and 2 from pushing in until all items currently in the pipe system complete. Once all is complete items in GROUP1 push to pipes 1 and 2 equally, and GROUP2 pushes to pipes 3 and 4. So they process simultaneously. Let's say we had a GROUP3 which could process at the same time as GROUP2, but not GROUP1. If GROUP2 finishes first it will still wait for GROUP1 to finish, however if GROUP1 finished first GROUP3 would allocated into the available pipes. We could even mark pipes 1-3 for GROUP3, so if pipe 3 is completed even though it's used by GROUP2, items from GROUP3 will go there.

This control is something we don't have with the ThreadPool, and even if we built a wrapper, we would not gain the same prowess we gain from implementing our own similar but different system.

Wednesday, February 15, 2012

Polymorphism: Structs, Interfaces, and Huh?


Ok, I know odd title, but I promise this will all get explained.

First, let’s start with some definitions of these concepts.

Polymorphism-

I like the Wiki version of this definition so here’s the link: http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming

For those who prefer not to click links and stay here, I will explain in a 1000 foot overview way. Basically in object-oriented programming, this is the ability to create a value, variable, function, or object that has more than one form. Shapeshifting so to speak, just as it would mean if not referring to coding. WOW! Simple enough right?

Structs-

MSDN does a fairly good job describing this:

http://msdn.microsoft.com/en-us/library/saxz13w4.aspx

Here, a struct is essentially the same as a class but it’s a value type. Just a little more limited, but can be less expensive, especially when using smaller objects that may be contained in large collections for example.

To get deep with it, a class is allocated in memory and allocates pointers (IntPtr) to the object wherever you place a field for reference type objects, classes.

However, structs, or value types, are allocated where you place them and do not generate pointers. This does mean they will copy and become unique allocations moving through the call stack and around the different scopes of your application, this can make them both easier and more difficult to control.

Interfaces-

MSDN also does their job well here:

http://msdn.microsoft.com/en-us/library/ms173156.aspx

Interfaces can be a complex topic for some, but to try to sum it up as simple as possible. They contain a reference to an object which implements the same methods, properties events that the interface defines. If you’ve dealt with C++ these will look a lot like class definitions in header files, and ALMOST behave like them. Interfaces cannot be instantiated and cannot define code implementation for it’s members.

Alright, Polymorphism in general is a huge topic of coding, so we’re not getting too deep, just showing one AMAZING example, though it may be hard to see all the benefits without trying it yourself.

If you’ve dealt with structs before you’ll know a few things about them, such as the inability to use inheritance, and the frustrating ref keyword when trying to pass them into methods as a reference type instead. So, their benefits typically get outweighed by the aggravations of these things. Here’s a tidbit that a lot of people forget, though structs cannot inherit they can implement an interface. It gets better though. Interfaces can inherit other interfaces….

Due to the two above facts, we can use polymorphism techniques to build a collection of structs which inherit each other, and can be passed as reference types without the ref keyword.

My example, which I’ve included the class diagram for, uses the following structs and interfaces:

  • IVector
  • IVector2
  • IVector3
  • IVector4
  • Vector2
  • Vector3
  • Vector4

Since the structs, the one’s without the ‘I’, cannot inherit each other all the inheritance tree is in the IVector-IVector4, and it just goes incrementally.

Ok, got that part, but what does this allow me to do?

void RandomMethod( IVector aV1 ) { }

The above method declaration accepts IVector, so what can be passed into this method? This method can actually accept ANY Vector type as it’s interface description. It could use IVector.AxisCount to determine which one was actually passed and handle it appropriately.

That’s one use, which is pretty cool. What about this one?


Vector4 v = new Vector4( 1,1,1,1 );

IVector2 v2 = v;

Will this even work? YES, this just gave me a reference to the Vecto4, the object is obviously still the same object, but rather than converting the value, we made it accessible as a Vector2 interface. Of course you would need methods that accept the interface instead of the struct to use it. Hence why IVector2.ToVector2() exists. This is a simple convert, where if the internal object is not a Vector2, it converts it before returning it.

I know this is a lot to take in so I will stop here. Have fun!!!

Introduction

Hello All,

I just wanted to take a moment to explain why I’m even creating this blog before making my first real posting. This blog I am going to use to pull all of my development activity into a single location.

Those who know me already and have been watching some of my other posts on the RuneEngine v2 Facebook Page should know I post almost everything there as it is. However, there are things I reserve posting there as they are unrelated to the RuneEngine project or any of it’s inner workings.

So, basically anything I post there or anywhere else, will likely end up here as well.

A little about me though. My name is Danny Helms and I am a full time support agent for an Imaging SDK provider in Charlotte, NC and a part time faculty for CPCC SGD Department, as a programming instructor. I have been coding since I was 8 years old, so been a pretty long time now. One thing you may see as I write is that no matter how long I’ve been developing or how far I go, I’m always learning new things. It’s not only because the field changes and advances on a daily basis, but also because it’s already so vast it’s hard not to come across new things all the time.

You may see me mention use of languages in:

  • -C#
  • C++
  • WPF
  • Silverlight
  • SOME VB.NET
  • Javascript
  • May start some Java soon
  • ASP.NET is also something I will likely piddle with in near future.

Common SDKs I use:

  • Microsoft’s XNA Framework
  • WeiFenLou Docking API (May not use this as much as I am moving further into WPF development)
  • BEPU Physics Engine

Current Projects:

RuneEngine V2 Projects----

  • RuneEditor.API (Simple API for addons to the RuneEditor application)
  • RuneEngine (2D)
  • RuneEngine (Native)
  • RuneEngine (Reach, Mobile friendly)
  • RuneEngine (HiDef, the core project and most of my efforts go here)
Other Projects---
  • BitbucketReporting.API ( Utility API for working with Bitbucket's WCF API, included in RuneEditor.API )