1

I am running Delphi XE2 and trying to get familiar with the OmniThreadLibrary, I have 3.03b installed.

I have been looking at the Parallel.ForEach examples and am not sure of what's going on in the background (this may well be obvious later - sorry). Any information you can offer to help me better understand how to achieve my goal will be much appreciated.

Suppose I have some record that is just a container for 2 related values, a and b. I then want to run a parallel loop that returns an array of these records. Is it possible to do this using the OmniThreadLibrary?

For example, taking the MultithreadingMadeSimple ForEachUnorderedPrimes example as a base, can I do something along the lines of:

    function GetMyRecordArray(n: Integer): myRecordArray; {Just a type of Array of myRecord}
    var
      a, b: Double;
      record: TOmniValue;
      recordQueue: IOmniBlockingCollection;
      i: Integer;
    begin
      SetLength(RESULT, n)
      recordQueue := TOmniBlockingCollection.Create;
      Parallel.ForEach(1, n).Execute(
        procedure (const value: integer)
          begin
            a := {SOME FUNCTION OF value};
            b := {SOME FUNCTION OF value};
            recordQueue.Add(myRecord.New(a,b));
          end;
        end);

      i := 0; 
      for record in recordQueue do 
      begin
        i := i + 1;
        RESULT[i - 1] := record;
      end;
    end;

I know there are some pretty fundamental problems with the above code example but I hop you can understand what it is I'm trying to do.

Trojanian
  • 692
  • 2
  • 9
  • 25
  • 3
    Why do you need a queue? You can write directly into the array. You know which index to use. It is the integer param passed to your anon method. – David Heffernan Nov 17 '14 at 18:07
  • Thanks @David - for some reason I assumed the queue was necessary - not sure it's necessary in the referenced example then? Maybe it's just there for comparison with later methods. When is a queue necessary? – Trojanian Nov 17 '14 at 21:16
  • It would be better to stick to just the problem at hand I think. Can you fix the code up now? – David Heffernan Nov 17 '14 at 22:21
  • Yep - sorted, thanks. – Trojanian Nov 18 '14 at 00:05

1 Answers1

0

I had some confusion with the example - a queue wasn't necessary for this application. Appropriate example code would be:

function GetMyRecordArray(n: Integer): myRecordArray; {Just a type of Array of myRecord}
var
  a, b: Double;
begin
SetLength(RESULT, n)
Parallel.ForEach(1, n).Execute(
    procedure (const value: integer)
      begin
        a := {SOME FUNCTION OF value};
        b := {SOME FUNCTION OF value};
        RESULT[value - 1] := myRecord.New(a,b);
      end;
    end);
end;

So pretty much how you would do it normally just with Parallel.ForEach...

Trojanian
  • 692
  • 2
  • 9
  • 25
  • 1
    The Result array index is relative to `value`. – LU RD Nov 18 '14 at 06:32
  • In such code where you're just looping over a range and not using any special ForEach functionality, the new Parallel.For will give you better performance. The code is available in the SVN HEAD. – gabr Nov 19 '14 at 08:17
  • @gabr Thanks! This is a great bit of code by the way! :-) Where can I find the Parallel.For code? Also, is there a `Down To` implementation? – Trojanian Nov 25 '14 at 17:27
  • Parallel.For is implemented in the latest SVN version at http://omnithreadlibrary.googlecode.com. For and ForEach statements support `step` parameter which can be a negative number (`-1` for example) for counting down. – gabr Nov 26 '14 at 08:45