John Ratcliff's Code Suppository

A place where I insert my code into the anus of the Internet.

 

Saturday, January 10, 2009

Intel's giant screw up with the Intel Threading Library TBB



I got in a discussion on a forum about the Intel Threading Library and now that discussion turned into a rant. I have now decided to cross post that rant here to my blog. (I encourage you to read the entire thread of discussion on the Ogre3d forums, because there is a lot of interesting follow-up conversation. And, by the way, the purpose of this rant is to shame Intel into fixing their ridiculous licensing decision on a handful of header files.)

A very legitimate question to me would be, John, why did you write the JobSwarm threading library when Intel already has an awesome open source threading library called TBB?

Yeah, good question.

Here's the answer why......

-------------------------

>>This exception is actually very unrestrictive, in fact, that exception makes the licence of TBB less restrictive than LGPL. It is definitely usable in commercial applications and does not enforce GPL on your own code....

We must not be reading the same thing. According to the announcement, TBB is under GPL2. On their site they refer to a commercial version and a commercially 'aligned' version whatever that is supposed to mean. At the end of the day it is released under GPL.

Please read the GPL license located here: http://www.gnu.org/copyleft/gpl.html

It is a massive and dense document that would require an attorney to figure out. Now, I'm not an attorney but, but let me tell you this, our attorneys tell us that under no circumstances can we use any GPL code in any way shape or form in any of our projects here at work. I don't care what little 'caveat' Intel shoved into their readme file so long as it has the word 'GPL' anywhere near it, I cannot touch it at my job period.

Realize that all of the source I release is also used by me at my job. I consult with my employer and we make selective decisions as to what code we will release open source and what we will not. We release open source for a variety of reasons: generating good karma, generally being a nice guy, and hoping that we will benefit from improvements and bug fixes made by others, or from software created by others that incorporates our code.

By comparison, here is the MIT license. I don't need to provide a separate link because it is so short and sweet one is not needed. It says the source is free, do with it as you will, and don't blame me if something goes wrong. That, in my opinion, is the only license any true 'open source' project should be in. It certainly should be no more than a paragraph or two, a couple of hundred words at best, and not a massive document such as GPL.

By the way, I am not alone in my opinion on this topic. Here is a link to a developer who says almost word for word the same thing I just said. http://www.linuxjournal.com/article/5935

If you can't tell by now, I’m really annoyed that Intel has this fantastic threading library that they ‘want everyone to use’ but then release it under GPL; a license that prevents virtually any commercial software developer from using it; based on company policy if nothing else.

(WHAT IS EVEN WORSE IS THAT OPEN-SOURCE DEVELOPERS CAN'T USE IT EITHER! BECAUSE GPL IS A VIRUS AND EVEN IF MY OPEN-SOURCE PROJECT IS MIT THE MOMENT I PUT GPL CODE INTO MY PROJECT IT IS NOW INFECTED WITH THIS DISGUSTING VIRAL MEME THUS MAKING MY PROJECT USELESS!!!)

As I assume you know, it is corporate policy at virtually all companies that no GPL code can be used period. And, because of the damage GPL issues have raised, now many companies won’t allow any open source code of any kind, no matter what the license. Which makes the job of a commercial software developer a giant pain in the ass when he has to completely rewrite open source code just so that his company now ‘owns it’.

I know of one major company in particular that I do consulting for that has this restriction. I know from personal experience just how frustrating this can be. Until Intel removes the phrase 'GPL license' from TBB it will never be adopted by virtually any commercial projects.

The MIT license:

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Code Suppository Respository to move to Google Code



IMPORTANT ANNOUNCEMENT AS OF JANUARY 10, 2009!!



I will be leaving this page up, with the existing links for a while; perhaps another few months. However, the CodeSuppository Respository is officially moving to Google Code

I will be performing all of my open source development on Google code in the future and will, eventually, be removing all code from this particular page.

The first three projects released on Google code are:

JobSwarm : A lightweight, lock-free, multithreaded job scheduling system (often called ‘microthreading)

MeshImport : (Early alpha/design phase at this time) An open source plugin system designed to handle general purpose mesh data transfer between application components. Supports meshes, skeletons, bone weightings, and animation data. While similar to the OpenAssetImport library, MeshImport has a separate DLL plugin for each importer, thus making it easy for developers to create custom importers for their own projects, and allowing you to keep some importers open source and others proprietary. MeshImport is currently in early alpha, but will be getting a lot more support very soon. Another important feature of the MeshImport system is that it does not assume the data resides on a physical file on disk (a bad assumption made by the OpenAssetImport library.) One of the MeshImport plugins will, however, support the OpenAssetImport library to rapidly ramp up a lot of additional formats.


CodeSuppository: This will be the main location for the entirety of my complete collection of code snippets. They will be wrapped in a DirectX9 interactive application framework so that you can visually see and demonstrate each of the individual features. An initial release is now available which does, in fact, include almost all of the source for my various code snippets. However, I have not yet had time to write specific demo implementations for each samples. Those will come online as a I find time. There are samples for a few of the most useful, and frequently referenced, snippets on this site. Best Fit OBB, Best Fit Plane, and Convex Hull.

If you want to be a contributing member to any of these projects, please send me an email to: jratcliffscarab@gmail.com. Include your Google member name as well as information about yourself; website, qualifications as a developer, and interests. In general I will be willing to allow trustworthy and competent developers contribute to these projects.

Wednesday, January 07, 2009

CodeSuppository moving to Google Code



Over the coming weeks (months?) I will be moving all of my 'CodeSuppository' resources over to Google Code. If you want to be a contributor to any project, just send me an email with your Google account along with a little information about you.

So far, I have only moved the 'JobSwarm' multithreading jobscheduler to Google code. David Pangerl from the algorithms list took it upon himself to finish up the lock-free queue which now seems to be stable and working nicely.

The next task needed for the JobSwarm code base is for someone to revise the source so it will build on Linux, which would be nice.

Where is the JobSwarm project going in the future? As I begin to use it more for 'real work' in my own personal project I expect there will be enhancements and/or new component layers.

Things that might get added are:

* Job batches
* Job priorities
* Job and Job batch dependencies
* Inter-Job communication
* A lock-free tiny memory allocator for individual job processing.
* A message based system for managing the flow of control of job completion events.

The JobSwarm project is currently located here on Google code You can either sync directly to the source code using SVN or download the pre-built binary packages.

SVN: svn checkout http://jobswarm.googlecode.com/svn/trunk/ jobswarm-read-only

Friday, January 02, 2009

JobSwarm : A microthreading framework with lockless FIFO



(I'm trying to use Google Code for the first time. You can try getting the code from there at this link. Please read the latest post about JobSwarm on this site.)

I used part of my Christmas break to implement a system that I have been wanting for a long time. I call it a 'JobSwarm'. What it is, is a micro-threading library that can handle tens of thousands of extremely tiny jobs with almost no overhead.

In the sample program provided I compute a fractal by decomposing it into 65,536 individual jobs, each one representing 64 pixels of a 2kx2k image.

The usage pattern for the JobSwarm is as follows.

First, you create a JobSwarmContext. This is a single instance of the JobSwarm system. When you create a JobSwarmContext you tell it how many physical threads you want to use. You can either create a single JobSwarmContext for your entire application, or you can create different ones in various subsystems.

When a JobSwarmContext is released any currently executing jobs will have to be completed before the method can return.

To use the JobSwarm you simply inherit the pure-virtual interface 'JobSwarmInterface' and implement three methods.

They are:

job_process
job_onFinish
job_onCancel

You find this interface in the header file 'JobSwarm.h' and enclosed in the namespace 'JOB_SWARM'.

A simple example of how to use this is in 'fractal.cpp' and in the class 'FractalJob'.

The three methods are implemented as follows:

job_process : This is the actual 'work' this job is supposed to do. This code will operate in a seperate thread and, therefore, must be entirely thread safe.

job_onFinish : This is a method which is called when your job has completed. This method is invoked in the main thread (the thread which owns the JobSwarmContext). This allows you to do anything with results you may have computed during the 'job_process' call.

job_onCancel : This is a methd which is called when your job was cancelled. This method is called from the main thread.

To manage the job swarm you use the following methods on the JobSwarmContext.

createSwarmJob : This creates a single job to be processed.

cancel : This cancels a previously posted job. It is very important to note that this only marks the job to be cancelled! You cannot destruct the job until you recieve the 'job_onCancel' callback.

processSwarmJobs : This is a 'pump' loop method which is called from the main thread. This call allows completed and/or cancelled jobs to be despooled. This is a very lightweight call but if you forget to invoke it none of your job completion events will ever occur.

setUseThreads : By default the job swarm system runs using hardware threads. However, for debugging and/or performance comparison tests, it can be toggled on and off on the fly. Setting 'useThreads' to false does not close out the hardware threads themselves, it simply moves the 'work' of the individual jobs into the main thread when you call the 'processSwarmJobs' pump method.

I am releasing this JobSwarm code for a reason. First, I hope other people might adopt it and improve the code and I would, thereby, benefit from it. I was also frustrated in my efforts to find a very tiny and simple micro-threading solution by searching on the net.

This system could use some improvements. For example, in addition to needing a true lock-free FIFO, it also might be nice if it supported job priorities.

It also might be interesting to support inter-job communication, if that sort of thing made sense and/or was useful.

I am making this code available in two forms.

First, as a small console application with just a tiny amount of source code.

You can download it from JobSwarm.zip

The source included with 'JobSwarm.zip' is as follows:

fractal.cpp and fractal.h : A very simple fractal routine which can solve the fractal in a linear fashion or by breaking it up into 65,536 distinct 'jobs'.

JobSwarm.cpp and JobSwarm.h : The main JobSwarm system. Has no OS dependent code in it.

LockFreeQ.cpp and LockFreeQ.h : Provides a lock-free circular queue for a single provider / single consumer system. Also provides an API for a lock free FIFO, however the implementation currently does use locks.

main.cpp : The console demo/test app.

pool.h : A double linked list template class used by the JobSwarm to manage jobs. Minimizes memory allocations.

sgif.cpp and sgif.h : A snippet of code to save a block of memory as a GIF image.

ThreadConfig.cpp and ThreadConfig.h : A wrapper layer to hide OS dependencies for threading related calls. Intended to be multi-platform but the current implementation is only for Windows.

The second application is a larger framework called 'ThreadFrac', which provides an interactive graphics application which allows you to visually see the performance differences when toggling the job swarm on and off on multi-core machines.

You can download and install it from ThreadFrac.exe

I look forward to bug-fixes, improvements, and feedback from the development community.

Thanks,

John

--------------------- Revision update January 3, 2009 --------------

I made the following important revisions to the JobSwarm.zip download.

  • I removed the source files 'fractal.cpp' and 'fractal.h'
  • I revised the 'main.cpp' to act as a much simpler example program on how to use the JobSwarm system. Simply look through and/or step through the code that is there.
  • I created two separate examples of how to use the JobSwarm system.
  • First : One class with a callback interface is created for each separate job. This may be the most common use case but requires more setup and memory allocation in some use cases.
  • Second: A single class receives callbacks for all of the 'jobs' and it uses the user data and user id field to figure out just what needs to be calculated in that context.
  • I added support for a userData and userId field for jobs. This extra meta data is available as an optional additional information to pass into the job service callbacks.
  • I fixed a crash bug that would happen occasionally when trying to deconstruct the JobSwarmContext
  • This version was built with VC2008. If you have an earlier version of VC you won't be able to load the solution and project files. Simply create a new console app and add the source files, that is all you need to build the example program.



Thanks to everyone who previously downloaded the sample and gave me feedback. It was all very useful.