Cross-platform development for web, desktop, and, soon, mobile.
Sunday, March 14, 2010
Supporting multiple cores
With today's multi-core CPU's it seems that an application made with REAL Studio running on a single core is somewhat restricting. If you have a lot of data to process, large images to manipulate or other things that could happen in the background, it would seem that with a multi-core machine you could do this faster "if only REAL would make threads preemptive". We get a lot of requests for preemptive threads so that people can take advantage of multiple cores. In fact, this request is number 4 on the Top 20 list in our Feedback system.
It's been suggested that this should be "easy" to do. Just make threads preemptive (so that they will then run on any available core) and voila! Unfortunately, it's not that simple. Let's look at why the current threads are not preemptive. It's hard for you, the developer, to work with preemptive threads. Some languages, like Java, have language features built in to them to try and help make this less work, but it is still hard to get right and very hard to debug when you don't. Much of the framework would need updating to be thread safe and your application's user interface is not thread safe on any platform because the operating systems themselves don't have thread-safe user interface code. If you access something from a pre-emptive thread and that something is not thread-safe, there's a very good chance your application is going to crash. We have had to go to a lot of extra work just to make the threads you have today work without causing problems.
The REALbasic language already has functions like mutex and semaphores that help you make a multi-threaded program. But you have to protect every place you might set a value that could be shared by many threads. This would mean protecting any globals and pretty much anything that is not local to the method or the thread being executed. That's very different than what you have to do today and a lot more work. It's just not "simple" or "easy to use" the way most of REAL Studio is designed to be.
The end goal is to use all cores and thereby make your software more responsive, faster, or able to handle more data, do more things all at the same time. There's been a way to do this for as long as REAL Studio has supported building console applications. The design is to create a main application (GUI or not) and use other helper applications to run separate tasks. The main application and the helpers can communicate in any one of several ways: IPCSockets, TCPSockets, UDPSockets, XML, files, or just about any other way you can dream of. The upside to this way of solving the problem is you can design and implement the main application and the helpers independently and use the debugger to debug each independently. You can use any data in either program in the same way you always have. You don't have to worry about the framework being thread safe as the helper and main application run as completely separate processes with their own memory space. Most importantly, you can do this today.
In fact, some REAL Studio users are using this technique today. John Balestrieri used this technique for a large data processing application. You can read about it here:
I'm not going to say it's simple.You have to think about what portion of your application can be segmented out into a helper console application. You have to design the communications between the main and helper applications. You have to write, test and debug them. But you don't have to worry about variables changing mysteriously because some other thread changed the value. You don't have to use lots of mutex's or sempahores to block other threads from altering things when you least expect them. And you can use the entire framework that is available to console applications. If you need pictures and graphics that are not available in console applications, you can write faceless GUI applications. Last but not least, you can run as many instances of these helper applications as your computer (or all the computers available to you) can run.
If you think you need preemptive threads today, try the helper application approach and I think you'll be pleasantly surprised at how well it works.