I am working on a small threading library that I started –and basically finished –today. First, I decided to use boost, but after searching through their documentation on how to build the .lib file and some other issues, I decided not to use boost. So, far, I have a simple yet powerful threading implementation. I started this because of the nonsense license agreements that most people, and companies attach to their products. Instead of being clear and stating: “You must buy a license if you wish to incorporate our library into your project,” the message is usually very obscure. After I decided to create a threading library, I was set on making it lightweight. I actually had my library running using boost threading, but after going through the unhappiness of finding out that I had to build a .lib file to compile with their library, I removed all the boost code. Everything has its place, and boost::thread is too annoying for me to integrate into my project despite it’s benefits.
Since I am mainly focused on Windows development, and Microsoft’s documentation is much better than boost –plus there is no need for any special library building–, I went with a Windows implementation (I hope that wasn’t a run-on sentence!). In order to incorporate the library, just include the header and cpp file. It will automatically initialize itself allocating same number of threads as there are cores. Parallel_For takes a start number, and an end in the form [start, end), and the third is the number of times you wish the work to be divided — or split — up.
Here is the code for a tester program. I had to use the float global and output it to the console, otherwise, the compiler would have optimized it away since I was never using the computed results. This forces the compiler to run everything, because I am using the results of all the computations. In case anyone has ever ran into a problem where you were attempting to time your program and always received a time of zero seconds, the reason is because the compiler optimizes away most of your program.
As of right now, the ONLY FUNCTIONS USERS SHOULD CALL ARE Parallel_For, RunTask, Wait, WaitForAll, and SetThreadingPriority. The other functions, and variables are all for internal use only. I will continue to add to the library, but right now, I cant think of anything else that I need.
-Task based library
-Work Stealing (if one thread runs out of work, it will steal work from another thread so it continues to work)
I have ran many tests on the speed of parallel for. It is difficult because of how the cpu can automatically increase the speed of cores that are being utilized (ruining the numbers). But, in general, I received a 400% increase in speed on my i7 processor 4 core processor. Bear in mind, that any work given to the threading library should be decent sized. Remember, that you are going to break the work up into chunks to be processed, so think of the smallest piece of work that will be given to a cpu and try to figure out if it is too small. If it is, then decrease the split number in the Parallel_For, of just assign the single task via the RunWork() and it will be mapped to a single thread to be worked on.
Also, on my i7, 8 threads are created because of hyper threading. Now, hyper threading does not mean that if you have 4 physical cores, and each core runs as two, meaning 8 cores, that you will get an 800% speed up. The most speedup you will get is a little over 400% because
Hyper-threading works by duplicating certain sections of the processor—those that store the architectural state—but not duplicating the main execution resources. This allows a hyper-threading processor to appear as two “logical” processors to the host operating system, allowing the operating system to schedule two threads or processes simultaneously. When execution resources would not be used by the current task in a processor without hyper-threading, and especially when the processor is stalled, a hyper-threading equipped processor can use those execution resources to execute another scheduled task.
This basically means that hyper threading ensures that your processor is always working by having a backup thread ready to go in case the current thread has to pause for some reason. There still can only be one thread working on a core at a time. There are many reasons why a thread would pause: Sleep() could be called, cache misses, memory fetch. on and on. In that time where the cpu would normally be twiddling its thumbs, the other thread starts to run: this is what hyper threading is.
Questions, comments.. lets hear em! Also, the library is free to use for anyone for any purpose– simple!
Click here for the Tutorial page
Recent Comments