Showing posts with label Parallelism. Show all posts
Showing posts with label Parallelism. Show all posts

Sunday, 10 August 2014

Thread Suspend, Resume and Abort

At first sight aborting, suspending or resuming threads (in the .Net arena) seems pretty simple, the Thread class sports methods for each of these 3 tasks. However, if you check the documentation, you'll see that both Suspend and Resume are marked as obsolete and highly discouraged:

Do not use the Suspend and Resume methods to synchronize the activities of threads. You have no way of knowing what code a thread is executing when you suspend it. If you suspend a thread while it holds locks during a security permission evaluation, other threads in the AppDomain might be blocked. If you suspend a thread while it is executing a class constructor, other threads in the AppDomain that attempt to use that class are blocked. Deadlocks can occur very easily.

As for the native Win32 funcion SuspendThread you'll find equally discouraging statements:

This function is primarily designed for use by debuggers. It is not intended to be used for thread synchronization. Calling SuspendThread on a thread that owns a synchronization object, such as a mutex or critical section, can lead to a deadlock if the calling thread tries to obtain a synchronization object owned by a suspended thread. To avoid this situation, a thread within an application that is not a debugger should signal the other thread to suspend itself. The target thread must be designed to watch for this signal and respond appropriately.

Thread.Abort is not marked as obsolete and no advice against its use is explicitly given in MSDN, but you'll find multiple articles and discussions (like this pointing against its use, just for the same reasons as Suspend.

The basic idea is that these methods are too invasive, they'll just Suspend or Abort a thread irrespective of what it's doing at that moment, which can be pretty risky. We need then a more collaborative way to do this, basically a Thread should be periodically stopping to do its main task and checking for Suspend or Abort requests at moments when it can really proceed with such order, aborting/suspending itself accordingly. Obviously the "periodically stop to do its main task" thing can be complicated to accomplish depending on what that main task is... but that's apart from the suspend/abort logic.

For Abort it seems pretty simple. A given thread would just check for an Abort flag, and when true, it would just end.

while(!this.abort){ //check for Abort requests
     DoWork();
}

For Suspend/Resume it's a bit more complicated, we can check for a Suspend flag, but once suspended, how do we check for the Resume order? Well, signals are the main communication mechanism among threads, so we should just use that, a ManuaResetEvent initially set as signaled, we would indicate a Suspend request by resetting it, and then send a Resume command by setting it again.

while(!this.abort){ //check for Abort requests
     DoWork();
     this.resumeSuspend.WaitOne(); //check for Resume/Suspend requests
    }

To really understand it you'll have to see this full sample

Sunday, 21 July 2013

The Odd Case of the Dual-core Netbook

I purchased a second hand laptop a few weeks ago (yes, it may sound like a bit retro/vintage thing to buy a netbook now when they've almost gone away... but let's say it took me a while to find a situation where a netbook could be useful to me).
It's a Vaio VPCW12J1E, and first of all, in case anyone is contemplating to get one, I want to state here that Lubuntu (light Ubuntu) works like a charm on this machine. WiFi will work nicely out of the box, sound card, everything, even the key shortcuts for brightness and sound! and it's absolutely astonishing to see how little memory it needs, really amazing, much more when we've got used to such resource hungry crappy software like Android...

This netbook already came with Windows 7 starter, which works pretty horribly performace wise, but it's not a Windows thing itself, it's something with the tons of (unnecessary) software that retailers add to it...
Well, the thing is that to my surprise Windows 7 tells me that I have a dual-core processor, which was quite unexpected cause it seemed to me that most netbooks (and more from that time, 2009) are single-core machines.

Windows Device Manager:

Windows Task Manager:

However, the Lubuntu Task Manager (lxtaskmanager) tells me it's a Single Core machine, pretty odd:

As you can see from one of the screenshots above, this is an Atom N280 processor, and as I suspected, Wikipedia tells us it's a Single-core Processor, so WTF? After a few searches the answer revealed itself in some forum, it's a Hyper-threading (HTT) thing!

Hyper-threading, wow, that brings up some old memories. A long while ago I was pretty much into how hardware works, and I quite well remember having printed and read some material about this "Virtual MultiProcessor" kind of thing, back in early summer 2002 (at that time the Itanium also seemed like the new king of the party) In a few years Multi-core processors became common place, and the Hyper-threading thing just was no more (or at least that's what I wrongly thought).
In short (not just to save space, but because I have a minimum knowledge about this topic), in an Hyper-threading processor some units in the processor core are duplicated (but not all of them, so it's very far from being a Multi-core/Multi-processsor), so that under some conditions it offers some sort of multiprocessing. The Operating System will see it as 2 cores, and will schedule 2 threads simultaneously, and then depending on the instructions/state of the processor, sometimes some sort of parallelism will happen.

This has made me muse over concepts I had almost forgotten, like the Processor Pipeline and Superscalar processors. Well Superscalar and Hyper-threading seem quite related, as in both cases some functional units in the processor are duplicated in order to provide some form of parallelism. This wikipedia entry is quite elightening. My understanding then is that with superscalar techniques (the attempt of) parallelism happens with instructions belonging to the same thread/process, and without any knowledge on the OS side, while with Hyper-threading, this (attempt of) parallelism happens between different threads/processes, and needs of the OS taking part on it.

This thing of Lubuntu's Task Manager showing only 1 processor made me wonder whether my OS would have the Hyper-threading support enabled, so I did a couple of checks to verify that HTT support was enabled:

  • sudo dmidecode

    where the status: Populated, Enabled means that HTT is enabled
  • run top and press the "1" key, so that processors are listed (Cpu0 and Cpu1):

This last check was particularly odd. As HTT is a very limited form of parallelism, it would appear fine to me if Linux decided to show me a single processor, but the fact of top displaying 2 processors and the Task Manager displaing 1, is confusing to say the least

Thursday, 17 May 2012

Bruce Eckel, Actors and more

As a Programming languages freak I'm a big advocate of Polyglot programming, so this presentation in infoQ immediately caught my eye. I was greatly pleased when found out that it was written by Bruce Eckel. It's been a very long while since I read his classical Thinking in Java, and even read part of Thinking in C++ (even someone with such distaste for C++ like me has to acknowledge that it's an excellent book), so it's good to see what Bruce's mind has been working on lately, sure it can offer direction :-) Based on this presentation it seems like he's been much into Python and Scala.

I have to painfully admit that in the last years I've been quite disconnected from Python. On one side, JavaScript and Groovy (and even C#) completely fulfill my need for freak-advanced-cute features, and on the other side I think I never fully bought the syntax (each day I'm less willing to move away from "C syntax").

As for Scala, it's one of the many things in my list of cool stuff to play with (even when the geek in me is much more of a Groovy type), along with other topic mentioned by Bruce, the Actor model. I've got zero knowledge about "Actors oriented concurrency", but I remember having first heard about this paradigm some years ago through a Microsoft Research Project named Axum. It seems like that .Net language with built-in Actors is now discontinued, but some of its concepts have made into the .Net framework itself or some other projects. Well, too many things I want to learn and too little time...

Wednesday, 22 September 2010

Multicore Bottleneck

Today, while reading some materials about Parallel Programming, partitioning datasets and so on, some old echos from the past came to my mind.

In most of the simple samples that I've seen lately, a bunch of data gets loaded into memory, and then the memory dataset is partitioned and each thread reads data from one of the data partitions. We do the whole loading into memory before launching the threads because otherwise different threads would be accessing to disk simultaneously and the I/O bottleneck would keep threads stuck while the I/O operation for other thread gets completed.

OK, I've said bottleneck. There's one that's been well known since long ago, Memory bottleneck. Years ago, as CPUs got faster and faster, the memory access technology was unable to keep up, and we had the problem of a fast CPU on hold waiting for the data retrieval from memory... We have caches and branch prediction to soften the problem, but anyway, it's still there.

Since some years ago CPUs speed has barely increased, but we have several cores, and more and more cores to come... This means, that it's not only that an operation will be we waiting for the memory to provide the data it needs, it's that multiple parallel operations will be waiting for the same memory to provide those data through the same data bus that we had years ago.
This sounds messy, so I thought sure there was some work around in place for this that I was missing (it's been a long while since the times when I was a hardware freak following the last improvements in chipsets and buses...), but after some googling it doesn't seem so, and in fact we can say that Multicore makes the memory bottleneck worse.