Jump to content
DavidJr.

TThread instances to run on separate CPU cores.

Recommended Posts

I have a question regarding TThread class instances vs using TTasks.

 

Is there a way to get 2 long running Tthread classes to run on separate CPU cores instead of using TTasks instances? 

 

I would like to have to threads run the entire time the app is open be ready to run some procedures.  They do this just fine,  however,  I just read up on TTasks and Delphi Parallel Programming Library, and I understand that the benefit is an automatic optimization of tasks by balancing the CPU load of each core..  but all I want to do is ensure that each thread run on a different core from each other.

 

 

Thanks.

Share this post


Link to post
1 hour ago, DavidJr. said:

all I want to do is ensure that each thread run on a different core from each other.

The first question you need to ask yourself when trying manipulate thread scheduling is: Am I smarter than the people that designed the OS thread scheduler?

 

If you can answer yes to that then go ahead and use SetThreadAffinityMask on your threads but I doubt you'll get the improvement you think. The two threads will still have to compete with all the other threads running on the system (and there's thousands of them) but now the scheduler can't move them to another core if their designated core is occupied. All you've achieved is to give your threads a handicap.

  • Like 2

Share this post


Link to post

Ok,  thats good to know.     Maybe this is a really dumb question,   but why isn't the TThread class instances handled the way TTask instances are from the beginning?   I am assuming that Any TThread instance I create and execute will run on the same core as my mainform thread,  is this true?

 

Share this post


Link to post
1 hour ago, DavidJr. said:

I am assuming that Any TThread instance I create and execute will run on the same core as my mainform thread,  is this true?

No, at least not necessarily - unless you only have one core. The OS thread scheduler will take care of running it on whatever core is available.

Share this post


Link to post
2 hours ago, DavidJr. said:

why isn't the TThread class instances handled the way TTask instances are from the beginning?

Because TThread is a lot older than TTask.

 

TThread is just a semi-thin low level wrapper around a windows thread. TTask has a much higher abstraction level and uses TThread internally (via the thread pool). You have the source code for both so go ahead and have a peek.

Share this post


Link to post
2 hours ago, DavidJr. said:

I am assuming that Any TThread instance I create and execute will run on the same core as my mainform thread,  is this true?

The entire point of a threads are to allow code to execute in parallel in the same process. 

Share this post


Link to post
15 hours ago, Uwe Raabe said:

The OS thread scheduler will take care of running it on whatever core is available.

I might be wrong here now as I believe this was on D7, but I think I met the same issue as @DavidJr. once.

 

I lost my key to my own password database so I put together a simple brute-force program to try and open it with all possible combinations, using as many TThread descendants as physical CPU cores (which was 4 in my laptop back then). During the first test run it was immediately clear that something is off, as the total amount of CPU used was 25%; I couldn't max out the CPU.

I seem to remember having some tries with BeginThread but I ended up running separate, single-threaded processes to utilize the rig's full protentional I managed to recover my passwords on (we had an unused 32 core Dell server which I could "borrow" for this task).

 

P.s.: It seems yes, it was solved one day. Using the following test I can increase the total CPU usage count all the way up just by adding more instances to the list:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.Classes, System.Generics.Collections;

Type
 TMyThread = Class(TThread)
 protected
  Procedure Execute; Override;
 End;

Var
 threads: TObjectList<TMyThread>;
 a: Integer;

Procedure TMyThread.Execute;
Var
 a, b: Integer;
Begin
 b := 13;
 For a := Integer.MinValue To Integer.MaxValue Do
  b := b XOr a;
 a := b;
End;

begin
 threads := TObjectList<TMyThread>.Create(True);
 Try
  threads.Add(TMyThread.Create(False));
  {...}

  For a := 0 To threads.Count - 1 Do
   threads[a].WaitFor;
 Finally
  FreeAndNil(threads);
 End;
end.

My laptop has only 1 CPU though, it's possible that the problem still exists, just on multiple CPUs?

Share this post


Link to post
17 minutes ago, aehimself said:

My laptop has only 1 CPU though, it's possible that the problem still exists, just on multiple CPUs?

No. There is no problem. If there are multiple threads then the OS will schedule them into different logic processor cores. Always has. You misdiagnosed your problem before. 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×