Using TParallel.For from the Parallel Programming Library

From RAD Studio
Jump to: navigation, search

Go Up to Using the Parallel Programming Library


The Parallel Programming Library (PPL) includes a loop function, TParallel.For, that allows to run its loops in parallel.

Within parallel loops, you must transform your operations into thread-safe operations. You can use members of the System.SyncObjs unit, such as TInterlocked methods.

Converting a For Loop into a TParallel.For Loop

Delphi:

For Loop TParallel.For Loop
for I := 1 to 10 do
begin
  // …
end;
TParallel.For(1, 10, procedure(I: Integer)
  begin
    // …
  end);

C++:

If you are using a Clang-enhanced C++ compiler, you can use lambda expressions:

For Loop TParallel.For Loop
for (int i = 1; i <= 10; i++) {
  // …
}
TParallel::For(0, 10, TProc1<int>([](int I){
  // …
}));

You can alternatively use a functor, which works with both previous-generation compilers and Clang-enhanced compilers:

For Loop TParallel.For Loop
for (int i = 1; i <= 10; i++) {
  // (Loop logic)
}
class TMyFunctor : public TCppInterfacedObject<TProc__1<int> > {
public:
  void __fastcall Invoke(int I) {
    // (Loop logic)
  }
};

// …

TParallel::For(1, 10, System::DelphiInterface<TProc__1<int> >(new TMyFunctor()));

If the loop needs access to one or more variables from the context outside the callback function, you must use a functor as follows:

  1. Declare variables in the functor class to hold copies or references to the variables that you need.
  2. Declare a constructor of the functor class that accepts the copies or references to those variables as parameters and initializes the corresponding functor variables with their values.
  3. Pass those variables to the contructor when you instantiate the functor.
  4. In your logic, in Invoke(), you can access those functor variables.

For example:

class TMyFunctor : public TCppInterfacedObject<TProc__1<int> > {
public:
  TMyFunctor(int a, TB *b) : a(a), b(b) {}
  void __fastcall Invoke(int I) {
    // (Loop logic)
  }
  int a;
  TB *b;
};

// …

TParallel::For(1, 10, System::DelphiInterface<TProc__1<int> >(new TMyFunctor(a, b)));

See Also