March 22nd, 2010 @ 00:27

Last autumn I had to do some particularly cpu-time consuming but completely independant computations on thousands of pictures (namely computing SIFT keypoints on high resolution images). Using my laptop, it would have taken hundreds of hours to complete (it took about 20 minutes per image), but it could be easily done in a distributed manner on dozens of machines.

I thus started writing a little cloud-computing alike framework to handle the distributed computations in a safe manner : the machines I was intending to run my computations on were public-access machines and could get rebooted at any time, so the computation (let’s call it task from now on) that was started on it would never end.

There’s no trick here, the user defines his tasks, an entry point which sets off the initial tasks, and that’s it. The tasks are stored in a workqueue, which is handled by a master node, which assigns tasks to the other nodes (actually, the master server is split in two, the “heartbeat” server which monitors slaves status, and a taskqueue server from which the slaves pull their tasks). If a node does not complete a task within a user-defined amount of time, the master assigns it to another node. Yet, if the initial node manages to complete the task before the second one, the task gets completed anyway (this prevents infinite task respawning in case of an unexpectedly long task).

The tasks may use data stored in either a file-like storage or in a database. Since the whole thing is in Python without any runtime restriction, any arbitrary code or binary can be ran through this thing, which feels like a great pro versus frameworks where only a few languages are supported. A nice feature is that each task can be associated to a file pack (holding e.g. binaries which will be ran by the task) which is automatically deployed or cleaned when the task is started on the node.

Let’s also mention that the slaves are automatically deployed based on a simple configuration file (through ssh/scp) ; that applications are easy to deploy as well (the initial files, the entry points and al are defined in a single config file, form which the deploy tool automagically creates the file packs, updates the pack data to the heartbeat server and plugs the entry point into the taskqueue) and that there are only a few deps for the slaves (python and python-yaml), and not much awful ones for the various servers (mostly add sqlalchemy to the slaves deps).

There are still some points I’d like to improve. I’d first like to make the master node dynamic, and not static like it is now. Nodes which may elect as master (i.e. those who may directly connect to the various storages) would use a distributed protocol to actually elect the master (I’ve worked on such stuff last year during a complexity course, see my (French) summary about the subject : Calculabilité Distribuée), and then broadcast to the other nodes the winner of the election. If the current master is unreachable at any time, the electable slaves would start doing the election process right away, but would still try to attempt to reach the master until the election is completed.
I’d also like to add a way to handle in a nicer way mixes of 32 and 64 bits architectures (i.e. provide a way to define 32-bit/64-bit specific initial packages).
Security is another matter, I guess I should probably add some chrooting to the runtime environment, and secure the transmissions between the nodes (note that there’s absolutely no notion of authentication in any part of the software at the moment).

The only problem is that whan I got to the point I had finished the framework, I had no time to write the little bit of script to actually test the whole thing, and a friend had thrown the pictures to his high-end quadcore computer, so I had no chance to test it on a real life scenario. I’ll try someday, though. If you want to give a try to the latest version I pushed (it lacks the database backend and documentation at the moment, though I intend to finish/test them and upload them someday soon), check the Cloudpy git repo.

March 22nd, 2010 @ 00:13

A few days ago, I discovered I had a miniUSB-A (or something along the line) plug on my beloved EOS 450D camera. Fun stuff, I could read pictures directly from the camera without having to swapping my SDHC card back and forth, at a pretty decent transfer rate (yet quite slower than through the cardreaded of my laptop).

I then discovered libghoto2, which is the library behind the Linux support of this feature. After a little bit of googling, I stumbled upon the gphoto2 website, where they mentionned that it was possible to command shooting from the computer and directly get the resulting image on the computer. Immediately tried and… it works great ! (though I haven’t figured yet how to get the picture on the sdcard instead of directly on the computer).

Not sure what I’m going to do with this, but I’m confident there is a bunch of hacking possibilities here. Maybe should I write a simple GUI on top of it someday to begin with. Or I could try building a motorized base and remote control the whole thing from my n900 (and attempt to do things like Paris 26 Gigapixels). Hmmmmm…

March 20th, 2010 @ 01:40

Last summer, I went to INRIA Sophia Antipolis (INRIA is the French research institute for computer science, basically ; Sophia Antipolis names a group of villages near Nice and Antibes (on the Côte d’Azur) on which are installed quite a lot of technology businesses, among which HP or Amadeus) for a 3 months internship in PLANETE project, under the advisory of Mathieu Lacage, a great software engineer.

Before any extra details, let’s point to the code, the report and the slides. There are also some slides somewhere in the wild which were made for a quick talk given by Mathieu at ns-3 workshop at SIMUtools 2010.

The goal of the internship was to enable the seamless use of multicore parallelization in ns-3 network simulator to speed up simulations.
The obvious idea behind this project is that with all the trends on going more and more towards highly multicore architectures even for personal computers, such a change would possibly allow large speedups without having to directly throw a lot of hardware in the balance and without requiring most likely complicated configurations from the user.

Our goal was to make theses changes entirely transparent for both developers (i.e. those working on improving the ns-3 framework — routing stuff, devices handling…) and users (i.e. those using ns-3 to simulate their protocols…).

Before going into the optimization details, let’s mention the basic idea of the algorithms that we used for the synchronisation of the execution units (the cores, in our case), algorithms which are part of the conservative synchronization algorithms class (as opposed to optimistic algorithms class).
We first tried a message-passing based approach, namely the Chandy, Misra, Bryant algorithm. The whole idea in this algorithm is that each node knows how far in the future it can avance without any risk of simulation desynchronization. This is based on knowing the physical transfer delays, plus the current date of the neighboring nodes ; date which is passed through recurrent messages. This way, under certain conditions (namely that no link has a null transfer time), the simulation will safely advance.
We found out that this approach would lead to no performance gain due to the amount of messages which have to be passed compared to the actual amount of stuff done per time unit.
We then used a barrier-based synchronization algorithm : at each iteration, a global maximum date is determined, based on the current date of each node and the physical transfer delays (again). All the node are thus allowed to process events up to this date, then wait at the barrier, and then go to the next iteration when everyone has reached the barrier. The actual barrier implementation is a fun part, which is described in the report. From a trivial semaphor implementation to a fully optimized, tree-shaped implementation, performance gains of over a 100 fold can be observed.

One of the usual challenges when doing parallel computing is to define a proper partition of what each execution unit does. For instance, when working on a network of nodes (which are computers, routers…), which nodes should be handled by which execution unit ? Since we don’t want to ask the user about what he thinks would be the best, and since we can’t just use topology clues to make a good partitionning (because it also depends on the actual dynamics of the network, which we can’t predict), we had to use a dumb solution and make it smart. The solution we found there was to have both dedicated and global nodes : a given percentage of nodes is dedicated to each execution unit, while a global pool of nodes remains undedicated. When an unit has finished processing it’s own dedicated nodes, it starts picking nodes from the global pool and process them. This way, these units won’t waste their time waiting for other units which have to handle more complicated nodes in their dedicated set, thus requiring more processing time just for the local set.

Now you are going to ask, why not just use a global pool and let all the units directly pick nodes to process from there ? The whole problem is that this global list must be protected, two threads just can’t pick stuff from it at the same time — this would lead to awful memory corruptions, and probably more. Consequently, we need to use either mutexes (i.e. locks) or atomic operations to modify the list. Atomic operations are cheap compared to locks, and yet they are still at least 10 times slower than normal operations. This justifies the whole dedicated + global pools approach.

Now, there were more thread safety problems. While most of them were easily disarmed for minor performances loss (such as disabling free list or caches), there was still a major issue : reference counting. Indeed, in order to be as user-friendly as possible, ns-3 provides (and heavily uses) a reference counting system to ease memory handling for users. The whole problem there is that the counters might be accessed concurrently by two threads at once. What happens when a thread references an objet at microseconds before another thread unreferences it ?
An usual i++ operation is usualy done by taking i from memory to a register, adding 1 to it and putting it back to memory. Now, if the original reference count was 1, we could have the first thread taking i = 1 from memory, the second one taking i = 1 from memory, remov 1, putting i = 0 back into memory, then figuring i == 0 and trashing the objet, then the first threading adding 1 locally, and putting i = 2 back into memo… wait, this memory has been unallocated. Game over.
Again, a possible solution is to use atomic operations. Oh right, they are awfully expensive. Don’t care, let’s try, there must not be that much ref/unrefs going around there. And then… ow, actually, we just catched a plain 100% runtime increase.
While we fixed some of the stupidities that lead to such horrible increases, the problem was still on.
We tried to use thread local storage to maintain a per-thread reference count, but this did not really solve the problem, just helped.
We finally tried to use thread local buffers of Ref/Unref operations, which would be batch-ran by a single thread. This lead to nice performance improvements over the previous solutions, but if I remember correctly under certain unknown conditions the code would badly crash or eat all the memory. Urgh.

Still, in some conditions, I still managed to get over 20% performance improvement with 8 threads (iirc).

The conclusion of all this is that multithreaded programming is definitely not a trivial problem and that converting an existing software to gain from multithreading is not that easy. For more information, numeric data and all, check the report.

Now, I have had no time since middle September to work on the issue, but I know Mathieu has. It’d be awesome to have some news from him here… To be continued, hopefully.

March 20th, 2010 @ 00:42

A friend of mine arrived in the US one week before me, and when he told me his department had to pay $8 a month to the university (namely PSU) computer services for his computing account (email, computer login…), I was like, wow, this is theft.

One week later I arrived in Pittsburgh and CMU, quickly got a computer account. While browsing the various docs about their computer systems (I was trying to login into a “general purpose Linux machine” which I supposedly had access to — I actually hadn’t since they had forgotten to create the account on this specific machine), I discovered that the monthly fee for an user account at CMU was $105. Still stunned.

Let’s mention that activating an ethernet outlet is also a charged service, just as registering a machine on the network (so yeah, you (or your department) have to pay both the ethernet outlet activation fee plus the machine registration fee). Isn’t this whole system crazy ? Isn’t it normal work to activate an outlet on a switch configuration/plug a ethernet wire in the said switch or to hit the validation button of a probably automated script to add a machine to the network ?

March 19th, 2010 @ 04:20

I seriously wonder what’s wrong with French names here in the USA.

  • My landlady has my email saved as Guilluame <guillaume@…>
  • The guy at the bank managed to swap my firstname and lastname ; does Seguin really sounds like a firstname ? (well, he also managed to make a typo in my pin code while recording my file into the computer system, which lead me to great lengths of stress when I figured that the damn ATM definitely wouldn’t let me use my long-awaited debit card [let’s concede him that it was an uncommon operation, since usually everything is directly done on the computer (and the pin code is typed by the user and double checked) but they were experiencing a computer systems upgrade at the exact time I came in to get my account opened)
  • Most people can’t pronounce Guillaume right, even if I tell them to just say William and that it sounds quite the same they won’t quit trying on their own and producing pronunciations I wouldn’t have thought possible (not that I really care about this, it’s rather fun than anything else :p )
March 19th, 2010 @ 03:55

Before leaving France, I called my French health insurance (namely MGEN), telling them that I’d be in the USA for 6 months, and they told me like, “well sure, no problem, just fill these two forms and email them back to us, we will move you to our international section real quick and you’ll be fine”. One month later, and almost 4 weeks after my arrival, they finally processed my request and I’m about to be moved to the said section… as soon as I pay by check a certain extra amount of money. Wait… you know that I’m abroad and that I can’t seriously send this check, right ?

March 19th, 2010 @ 03:37

Chipping in the buzz, but I’m getting really annoyed of the “Stop Health Care Arrogance” ads. I believe they easily amount for 75% of the ads I’ve seen today. Not that I don’t care, but erm, I’m not really going to call my US congressman :-|

February 17th, 2009 @ 18:44

Just upgraded this WordPress to 2.7.1, and wow, this new automatic upgrade system is great. All I had to do was type my ftps logins and hit the Upgrade button. Congrats and thanks to the WordPress team !

October 30th, 2008 @ 08:42

Disclaimer : this post is completely useless, yet I like it

Short story : linking two individuals seems to be just a matter of having enough data about them.
Long story : I’ve been claiming for a few weeks that there is one girl (which I don’t know personally, just visually) here at the ENS who looks like my girlfriend (actually, I’m claiming my girl friend looked like her 2 years ago, but that doesn’t matter much). I was able to show her to my girlfriend last week (by the way, ENS “Urban Night” was great :) ), and she now thinks I’m completely crazy since, according to her, there’s nothing in common between them.
Since I hate being wrong, I went on and found the girl’s name after some extensive ENS students directory lookup, which lead me to her Facebook profile. I didn’t even have to run some facial comparison engine, the missing link appeared immediately. It was so obvious I was astonished I hadn’t guessed it before. The resulting matching is simply perfect.

They both love Nutella.

September 23rd, 2008 @ 13:09

Compiz Fusion Logo
Here is a new Compiz Fusion release, tagged 0.7.8, bringing a good bunch of bug fixes and quite a lot of work on animation plugin

The official announcement is available in Compiz Fusion Community list archives.

Have fun using Compiz Fusion!