Thursday, December 01, 2011

Fibonacci Numbers the Weird Way

Yanniel recently posted two ways to generate Fibonacci numbers, here are two more.

Generating Fibonacci numbers with an enumerator

for i in Fibonacci(10) do
    Writeln(i);
Of course you need a Fibonacci-implementing enumerator. I wrote one on 2007 and it uses the iterative approach. Read more in my old article Fun with enumerators, part 6 – generators.

Generating Fibonacci numbers with anonymous methods

This one was prepared for ITDevCon 2011 as an example of tricky (but pretty much useless) example of what can be done using anonymous methods.

Tuesday, November 29, 2011

Per-object locking

I was always holding the opinion that locks should be as granular as possible. Putting many small locks around many unrelated pieces of code is better then using one giant lock for everything.

To make this simpler, OmniThreadLibrary includes a very useful record called TOmniCS which allows you to do locking without doing any upfront initialization. Just declare it and you’re ready to go. [You can read more about it in my previous blog post.]

Monday, November 28, 2011

Atomic interface initialization

OmniThreadLibrary includes (in the OtlSync unit) a neat record called TOmniCS which wraps IOmniCriticalSection interface (which in itself is just a wrapper around the TCriticalSection) and allows you to use it without an explicit initialization. You just declare a variable of the TOmniCS type in your code and then call Acquire and Release methods of this variable and everything is handled for you.

type
  TOmniCS = record
  strict private
    ocsSync: IOmniCriticalSection;
    function  GetSyncObj: TSynchroObject;
  public
    procedure Initialize;
    procedure Acquire; inline;
    procedure Release; inline;
    property SyncObj: TSynchroObject read GetSyncObj;
  end;
As records don’t provide automatic initialization via parameterless constructor, the code is slightly tricky. The record contains a field (ocsSync) that contains the interface reference used to do real work. This interface is initialized in the Initialize method, which is in turn called from the Acquire and Release.

procedure TOmniCS.Acquire;
begin
  Initialize;
  ocsSync.Acquire;
end;

Tuesday, November 15, 2011

OmniThreadLibrary needs more unit tests

Eh. How true. :( Care to step in?

It’s really simple. Take a sample application (for example 37_ParallelJoin), check what it’s doing and convert it into a unit test. [In this example, first button should cause a wait of about 3 sec and second button should cause a wait of about 5 sec. That’s all.] If the application you have chosen seems too complicated to be converted to a unit test, just ignore it and select another.

Why? Because I’ll be converting OmniThreadLibrary to support 64-bit and FireMonkey in the next week and I really could use a safety net which would ensure at least that I don’t break everything at once.

Why you? Because I’ll be converting OmniThreadLibrary to … but I already said that. If you can spend some time on that, then I don’t have to and everything will be finished quicker.

For really curious people – why 37_ParallelJoin? Because it is broken in the current SVN version. Parallel.Join.NumProc is not working correctly and I only noticed it by chance. [Fixing the bug right now …]

If you like OmniThreadLibrary but don’t feel competent enough to help developing it, this is your chance to step in and help the development effort!

Wednesday, November 09, 2011

TOmniValue handles arrays, hashes and records

Arrays

For quite some time, TOmniValue record has the ability to store arrays. You would use

TOmniValue.Create([1, 2, ’OTL’, TButton.Create(nil)]) 
and some magic would store this array inside TOmniValue.
The problem, though, was that this magic was quite lame. The array was converted to a ‘variant array’ and you could only access its elements as Variant type. This, besides other things, meant that it was not simple to store pointers, interfaces and objects in TOmniValue array. Or, better said, it was simple to store them but not simple to retrieve them. You needed some ugly casting like

o := TButton(NativeUInt(ov[1]));
Since today, TOmniValue supports native arrays, that is, each item in the array is again of the TOmniValue type.

Thursday, November 03, 2011

OmniThreadLibrary in Practice [2]–Background Worker and List Partitioning

Today’s question was asked by Žarko Gajić, the excellent maintainer of About.com’s Delphi section.
Here's my (simplified) task I would like to solve using OTL (Delphi XE) - my real-world task is somehow more complicated but can be described as:
input: a string. output: a TStringList containing characters (one per entry) of the input string.
Example: input: "delphi"
A background thread ("master") grabs the input string and splits it into several pieces (let's say 2): "del" and "phi". For each of the split strings a new thread ("child") is created that fills in the TStringList (output) with characters from the section of the string it receives.
At any time the "master" thread could be signaled to terminate (from the app's main thread) all child threads (and itself).
When everything is done the app's main thread processes the string list.
Preferably, the order of the characters should (when all ends) be 'd', 'e', 'l', 'p', 'h', 'i' (note that characters are actually items in the resulting string list).

Saturday, October 29, 2011

ITDevCon 2011–recap

ITDevCon 2011 has closed its doors and I’m back at home, completely washed out. It was tiresome but it was also fun!

All the sessions I’ve visited were interesting and I always managed to learn something new. If I would have to expose three most important products I didn’t knew before, I would mention (in the order I learned about them) CopyCat, a great database replication engine which you can compile into your application; Delphi Relax, an extension to Delphi’s WebBroker and DataSnap REST architecture; and DORM, a new ORM for Delphi.

Thursday, October 27, 2011

ITDevCon 2011

Just few photos from the opening session …

P1070456P1070458P1070462P1070463P1070464P1070465P1070470

Wednesday, October 26, 2011

Nasty COM regression in XE2

David Heffernan found a nasty RTL bug in XE2 COM implementation.

Is COM broken in XE2, and how might I work around it?

I’ve found a workaround (see the link above), but it is ugly and this should really be fixed in the next XE2 update so please – vote on the QC #100414!

Update: XE2 Update 2 fixes the bug described above. Great response time from Embarcadero!

Saturday, October 22, 2011

Multithreading Made Simple–additional material

Thank you for listening to my CodeRage 6 presentation! I’m very sorry that there were some issues with the sound that were caused by network problems :( If you want to look at the presentation again (or for the first time), please go to the Embarcadero CodeCentral or download the presentation from my Dropbox.

To help you understanding the complicated world of multithreading I’ve repacked the complete presentation in a longish PDF with slides and a transcript of my talk. (Actually, it was done vice versa – first I wrote that script and only then I prepared the presentation based on the script.) You can also download the code that was used for the presentation.

If you have any questions or if you asked me something after the presentation and I didn’t understand your question and answered something completely unrelated or even if my answer was too short and you want to learn more - feel free to leave a comment here or open a new topic in the forum.

Friday, October 21, 2011

Multithreading Made Simple

Keep in mind – my session on high-level OmniThreadLibrary stuff goes on air at 06:00 AM PDT / 15:00 CET.

Thursday, October 20, 2011

OmniThreadLibrary in Practice [1]–Web Download and Database Storage

From time to time I get a question on the OmniThreadLibrary forum that could be of interest to other OmniThreadLibrary users. As I believe that many of you don’t follow that forum I have decided to repost such questions on the blog (and provide answers, of course).

The first question in this series was asked by GoustiFruit:

I need to download a list of web pages, extract data on them and then store these data in a SQLite database. The downloading/extracting part will happen in multiple threads (I'm using Synapse), but querying the database needs to be done asynchronously as I can only have one concurrent access to it.
So I'd like to know how (conceptually) I could implement that ? My first idea is to run one single thread for querying the DB, run several threads for each Url to download/analyse and then exchange messages between these threads and the querying thread, with the extracted data as a parameter: does it make sense or am I totally wrong? I also read things about the connection pool concept but I'm not sure if it applies when only one connection is allowed at one time?

Sunday, October 16, 2011

CodeRage 6 is Starting!

Tomorrow starts the CodeRage week!

My presentation is scheduled for Friday, 21st, at 06:00 PDT / 15:00 CET, which is early for the West coast folks but great for East cost and us Europeans. See you there!

Tuesday, October 11, 2011

OmniThreadLibrary 2.2

Only three months since 2.1 and a new release is already here? What’s going on?

I had to change some things to make OTL work in XE2 and although I could simply release new files as a patch I noticed that I’ve also done quite some work on exception handling and that I could equally well wrap everything in a new release.

Here it is: ZIP, SVN, UML diagrams (provided by Rich Shealer; Rich, thanks!).

Friday, October 07, 2011

Hear Me at CodeRage

CodeRage 6 will start in ten days! Will you be there? I’ll be joining it for the sixth time as a listener and for the first time as presenter!
The exact date and time of the presentation was not determined yet (if you look at the session list you’ll see some empty spots – I’m one of them). I’ll let you know when the timeslot is fixed. In the meantime, go and register for the conference!
The topic of my talk you can probably guess – multithreading with the OmniThreadLibrary. Due to a limited session time and to attract as wide an audience as possible, I’ve decided to focus on high-level OTL functionality. The title of the talk is Multithreading made simple and it will deal with Async, Future, ForEach, Pipeline, ForkJoin, Join, and ParallelTask.

Wednesday, September 28, 2011

NeverSleepOnThreadContention–NOT!

FastMM is a wonderful memory manager, but it can slow down quite a lot when used in multithreading environment. While Pierre has implemented some conditional defines that could help the multithreaded code, namely NeverSleepOnThreadContention and SwitchToThread, I’m now making a point that you shouldn’t ever use them! Just see for yourself.

Friday, September 16, 2011

Meet Me in Verona

SpeakerButtonI know that XE2 on Win64, OS/X and iOS is all the rage but some of us (or is it most of us?) still have to make living in the Win32 world. That’s why my ITDevCon 2011 talks are not focused into specific technologies but into techniques and tools that will make your life easier. (At least your life as a programmer, that is.)

If you have time and you live close enough, come to Verona at the end of October and meet many interesting people. Lots of speakers, three separate tracks, free lunch and wifi – what do you want more? David I is rumored to be there, Marco Cantù will lead sessions all the time and you’ll have a chance to talk to me. I’ll be giving four sessions, some targeted at beginners, some at experienced programmers. (All between those extremes are also invited, of course.)

Monday, September 12, 2011

Life after 2.1: Parallel data production [Introducing Parallel.Task]

An interesting problem appeared on StackOverflow shortly ago – how to generate large quantities of data as fast as possible and store it in a file. (As one could expect) I wrote a parallel solution using OmniThreadLibrary, more specifically the Parallel.ForEach high-level primitive. I’m not posting the complete solution here, just the important part – a method that accepts two parameters, requested file size and output stream, and generates the data. Actual initialization of data buffers is delegated to the FillBuffer method which you can see in the StackOverflow post.

Tuesday, September 06, 2011

Life after 2.1: Pimp My Pipeline

While the biggest focus on the Pipeline improvement was on the exception handling, there were also some changes in the basic functionality.

The most important (and code breaking!) change happened to the Input function, which was renamed to From. If you now want to pass a input queue to a pipeline, use pipeline.From(queue).

Second code breaking change happened to the Run function which now returns IOmniPipeline (i.e. the pipeline interface) itself, not the output blocking collection. Luckily, both changes will be caught by the compiler which would not want to compile the old code any more.

Thursday, August 25, 2011

Multithreading is Hard!

I have known for a long time that there’s a potential race condition between two writers in TOmniBlockingCollection but I thought that it doesn’t present and clear and present danger. Boy was I wrong!