DavidJr. 1 Posted February 11, 2022 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
Anders Melander 1782 Posted February 11, 2022 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. 2 Share this post Link to post
DavidJr. 1 Posted February 11, 2022 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
Uwe Raabe 2057 Posted February 11, 2022 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
Anders Melander 1782 Posted February 11, 2022 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
David Heffernan 2345 Posted February 12, 2022 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
aehimself 396 Posted February 12, 2022 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
David Heffernan 2345 Posted February 12, 2022 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