0

During Executing of a Multithreading program I see 8 threads starting in the Delphi Event log.

(My CPU is a Intel 7 with 4 cores HyperThreaded so 8 Calculation Cores) but in my TaskManager at the Performance tab I see only 12% CPU usage and only one core calculating with performance up to about 70 - 80 %. Did compile my multithreading program with OTL usage and with ParallelFor usage, But still only 12% performance and only One core doing the work.

On my Form1 I have a ButtonClick procedure with the OTL parallel.ForeEach which iterates over items of a StingList. The StringList lines contains each a Name, a Path to a differend DataFile and a DataFormat of the File. The ForEach.execute() Starts a 'EntrySearch'procedure on other Unit, The EntrySearch procedure starts with the extraction of the info from the appropiate line of the Stringlist. In a 'While X < Y loop' is the data extracted from the DataFile through a AssignFile and While not eof,read the lines with data. Calcuclations are made on the Data until the 'While X < Y' loop ends

I can see that 8 (CPUcount) Threads are started at the ButtonClick procedure. In the TaskManager I see only one CPU core start working total of about 12% ProcessorUsage. When after the calculations the ProcessorUsage returns to 0% the .exe program is hanging and I have no controlover the program. From the little data I can extract out of the CalculationUnit I getonly data from the last started thread, as of this last thread makes the other threads stop and cannot make their caculations and can not terminate.

{the OTL in the ButtonClick procedure}
       Parallel.ForEach(0, StrList.Count-1)
       .PreserveOrder
       .NumTasks(CPUCount)
       .NoWait
       .Execute(
        procedure(const value: integer)
         begin
           CalcUnit.EntrySearch(value);
         end);

    {procedure on CalcUnit} 
    procedure EntrySearch(value: integer);
    begin 
     {extract Name, Path DataFile and DataFormat from StringList}
      While X < Y do begin
        AssignFile(qMSInputFile7, Path);
        {$I-} reset(qMSInputFile7); {$I+}
        While Not eof(qMSInputFile7) do Begin
          with qMetaRec7 do begin
            Read (qMSInputFile7, qMetaRec7);
             { Extract the Data}
           end; // While not eof
        {Make calculations}   
      end; // While X<Y 
    end;

What goes wrong? and how can I solve this. Thanks A lot.

Frits Molenkamp
  • 175
  • 1
  • 10
  • 2
    The first sentence is misleading. You mean during execution of your program rather than during compilation. Why is your program not being executed in parallel? The answer can be found in your program. – David Heffernan Oct 24 '14 at 08:10
  • 1
    You will need to show an [MVCE](http://stackoverflow.com/help/mcve) – whosrdaddy Oct 24 '14 at 08:34
  • @David Hefferman, Thank you, changed compiling to execution. – Frits Molenkamp Oct 24 '14 at 10:31
  • @whosrdady Thank you, I'll try to make a MVCE – Frits Molenkamp Oct 24 '14 at 10:33
  • 2
    Try using a different memory manager, e.g. scalemm or synscalemm. Also try using a thread pool and IOCP on Windows. – Ondrej Kelle Oct 24 '14 at 10:44
  • @DavidHeffernan - Why not FastMM? – Lieven Keersmaekers Oct 24 '14 at 12:13
  • @LievenKeersmaekers It doesn't not scale under thread contention – David Heffernan Oct 24 '14 at 12:23
  • @DavidHefferman, Thanks for Comment, I planned to study the OTL ThreadPool this weekend. hope to find a solution – Frits Molenkamp Oct 25 '14 at 09:54
  • Why won't you show code. If you won't do this then you should delete the question. – David Heffernan Oct 26 '14 at 06:45
  • @DavidHefferman Easy to say "show your code" or "show an MVCE". The two main units of the program I am working on, has together 15390 lines. If you don't want to think about a solution, then don't. But please don't add non-constructive comments. – Frits Molenkamp Oct 27 '14 at 08:33
  • @whosrdaddy I've been trying to make an MVCE but I did not succeed. Hopefully the following helps: Please See: I have added the question – Frits Molenkamp Oct 30 '14 at 08:39
  • Are you using global data that is compromised by the threads? Note that the question has changed from the original. We can't really debug code without seeing it. Use the debugger to see what is happening. – LU RD Oct 30 '14 at 09:44
  • @LU RD Thanks for you comment, I understand that decoding isn't possible without seeing it. I've been 5 days trying to make an MVCE, didn't succeed. No, No Global data is used. if you mean that more threads use the same data, but I search for this. – Frits Molenkamp Oct 30 '14 at 12:01
  • Why are you using `PreserveOrder` with a procedure that doesn't produce any output? Note that 12 isn't very surprising: 100% ÷ 8 = 12.5. Here's a simple debugging technique: While your task is running, and you can see that the other 7 CPUs aren't busy, pause your program. Look at all the threads' call stacks. That will tell you what they're doing, which should then give a clue about what they're waiting for instead of doing what you expected them to do. – Rob Kennedy Oct 30 '14 at 12:54
  • By global I mean data that is common within the scope of the threads. It's time to learn how to debug. A quick search "Delphi debug threads" gave [Debugging Multithreaded Applications with Delphi](http://edn.embarcadero.com/article/41175) and [Better multi-threaded debugging in the Delphi](http://stackoverflow.com/q/515036/576719). Using [OutputDebugString()](http://stackoverflow.com/a/11218509/576719) at certain places can be valuable to get started. – LU RD Oct 30 '14 at 13:24
  • @Rob Kennedy thanks for your comments. I did expect all 8 cores to work, seeing only one core doing the work was surprising. I am new in these Thread things and learning every Time. I have to focus on better debugging, Thanks for your help. – Frits Molenkamp Oct 30 '14 at 20:35
  • @LU RD thanks for your comments. yes I am new on threads. I will follow your links for better debugging. Thanks for your Help. – Frits Molenkamp Oct 30 '14 at 20:36
  • 1
    @LU RD Your comments where very helpful! Thank you. through the debugging link you gave I found indeed that my problem were the Global variables. My Calculation procedure is on a separate Unit, thinking that the whole unit was taken into the Thread. Now I placed the variables all inside the procedure My problem is solved. I learned a lot! Thanks Again Best regards Frits – Frits Molenkamp Oct 31 '14 at 15:40

0 Answers0