In this special musical number I’ve created a music video based on Jonathan Coulton’s Code Monkey written in Delphi’s Object Pascal.
[Download the code] [Download the video (mp4)]
In this special musical number I’ve created a music video based on Jonathan Coulton’s Code Monkey written in Delphi’s Object Pascal.
[Download the code] [Download the video (mp4)]
To follow-up with my Parallel For Loops skill sprint last week (lots of good resources there), today I did a deep dive into the Parallel Programming Library (PPL) including Futures, Tasks and custom thread pools.
Here are the slides:
And you can download my Tasks and Futures sample to see how to create, start, check and cancel both Tasks and Futures. Check out the C++ Parallel Examples to see how to use Futures and the PPL in C++.
Until the replay of my Skill Sprint is posted, you can watch this video from Allen Bauer covering the Parallel Programming Library Architecture from CodeRage 9.
Be sure to sign up for and check out the other Skill Sprints.
This is some code I wrote a long time ago as part of the TDAG mailing list. It calculates Factorials, the number of Combinations and Permutations. This is the mathematics, it calculates the number of Combinations and Permutations, it doesn’t create each different Combination and Permutation.
They take Cardinals as parameters because it doesn’t make sense to accept negative numbers. Keep in mind that factorials get big really, really quickly, so if you use too large of numbers then it will overflow even the Int64.
unit FactCombPerm; interface // Parameters are Cardinal because Int64 isn't Ordinal // Besides, Factorial(100) will overflow Int64 already. function Factorial(const ANumber: Cardinal): Int64; overload; function Factorial(const ANumber: Cardinal; const AStop: Cardinal): Int64; overload; function CombinationUnOpt(const ACount, AChoose: Cardinal): Int64; function Combination(const ACount, AChoose: Cardinal): Int64; function Permutation(const ACount, AChoose: Cardinal): Int64; implementation function Factorial(const ANumber: Cardinal): Int64; overload; // n! = n * (n-1) . . . n(2) var lCtr: Cardinal; begin Result := 1; for lCtr := ANumber downto 2 do Result := Result * lCtr; end; function Factorial(const ANumber: Cardinal; const AStop: Cardinal): Int64; overload; // Factorial with a stop point (needed in the optimized Combination routine // if no AStop is specified then is the same as Factorial var lCtr: Cardinal; begin Result := 1; if ANumber >= AStop then for lCtr := ANumber downto AStop do Result := Result * lCtr; end; function CombinationUnOpt(const ACount, AChoose: Cardinal): Int64; // n! // n_C_k = ---------- // k!(n - k)! begin if AChoose < ACount then Result := Factorial(ACount) div (Factorial(AChoose) * Factorial(ACount - AChoose)) else Result := 0; end; function Combination(const ACount, AChoose: Cardinal): Int64; // n! // n_C_k = ---------- // k!(n - k)! // with optimizations even! begin if AChoose < ACount then Result := Factorial(ACount, succ(ACount - AChoose)) div (Factorial(AChoose)) else Result := 0; end; function Permutation(const ACount, AChoose: Cardinal): Int64; // n! // n_P_k = -------- // (n - k)! begin if AChoose < ACount then Result := Factorial(ACount) div Factorial(ACount - AChoose) else Result := 0; end; end.
My original optimization had a bug in it, but Bryan Mayland fixed it for me. This is old code, and there are probably some options to optimize it better. I’d love input, suggestions, etc.
I hope you are all as excited about DelphiWeek as we are. On Wednesday we have CodeBattles scheduled. These are a fun way to show off your programming skills. We all use a Google, DocWiki and Stack Overflow during programming. The coding challenge isn’t a trivia competition, but an opportunity for you to show off your problem solving skills and use some of the latest features in XE7.
It will take place Wednesday 11-Feb-2015 from 8 AM to 10 AM PST. All coding will be done online during this time window via GoToWebinar.
The scoring is a combination of points based on features implemented and public voting. David I. is planning to make plaques to send the winner. I think it would be great to hang a plaque in the office with the winner’s names too.
If you want to take part in the CodeBattle, complete this short survey with your information. We are considering working with both teams and individuals, if we get enough sign ups for both. So far we already have a few individuals. It is open to all Delphi developers everywhere. Even if you are not comfortable with English, we can chat via Google Translate.
Interested? Sign-up today!
Talking with Darren Kosinski from the Embarcadero R&D team and his role in the FireMonkey platform. Also a brief introduction to the Parallel Programming Library, and Delphi Week 2015 (Feb 9th – 13th).
Parallel For Loops are a hassle-free way to supercharge your program with the Parallel Programming Library. The syntax is similar to the standard For loop, with the advantage of each iteration running on in a different task on the thread pool. This allows multiple iterations to run at the same time, taking advantage of the multi-core and hyper-threaded architecture common on laptops, desktops and mobile devices today.
Here is the replay of the Skill Sprint:
Here are the slides:
Update: I was chatting with Allen Bauer today and he mentioned that while you technically can use Queue and Synchronize from within a Parallel For loop, he wouldn’t recommend it because it will dramatically reduce the speed of the loop. It is still faster than a linear loop, but not as fast as it could be. I’ll leave these examples here, but keep that in mind when optimizing your parallel code.
Here is the syntax in Object Pascal. The stride is the first parameter is it is optional. It controls how the iterations are grouped when being sent to the CPUs. Min and Max are your usual start and stop range for the loop. The last parameter is an anonymous method that represents the code to be executed on each iterations. It takes an Index parameter that is either an Integer or Int64 that provides the value of the current iteration.
TParallel.For(Stride, Min, Max, procedure (Idx: Integer) begin if IsPrime(Idx) then begin TInterlocked.Increment (Tot); TThread.Queue(TThread.CurrentThread, procedure begin Memo1.Lines.Add(Idx.ToString); end); end; end);
Here is the C++ code syntax. It takes a event instead of an anonymous method.
// . . . TParallel::For(NULL, Min, Max, MyIteratorEvent); // . . . void __fastcall TFormThreading::MyIteratorEvent(TObject *Sender, int AIndex) { if(IsPrime(AIndex)){ TInterlocked::Increment(Tot); }; }
There are some great blog posts and videos on the Parallel Programming Library
Stephen Ball has a series of blog posts on the Parallel Programming Library, including a Quick Introduction and one on managing the thread pool. As Stephen points out, while you can customize the thread pool, that doesn’t alway mean you should. Malcolm Groves also has some great blog posts on PPL.
Danny Wind has a great Code Rage 9 session on the Parallel Programming Library (be sure to download his samples). David I. did the C++ version.
Allen Bauer, our Chief Scientist, also has a CodeRage 9 session on the PPL Architecture.
If you want to take advantage of the new C++11 Lambda syntax on Win64 and mobile, then check out this community article or watch this CodeRage 9 video snippet. Get Bruneau and David’s code for C++ and Parallel libraries.
Update: Keep in mind that a Parallel For loop isn’t always the best performance option, but it is really easy to use. Check out Stefan Glienke’s Stack Overflow answer for an alternative using the PPL TTask for even better performance.