[fpc-pascal] Re: Threads executing in sequence instead of parallel
Graeme Geldenhuys
graemeg.lists at gmail.com
Mon Oct 2 20:50:28 CEST 2006
Thanks Pete,
Even though Micha did manage to explain why my demos ran as they did,
I will try you demo anyway. Purely to see how big the output file
grows. :-)
Quick recap from Micha. The time slicing in Linux is much larger that
under Windows. This improves performance (especially on
calculations). See the link he posted for a full explanation. I
modified my Sorting Demo and added three more Bubble Sort threads.
Incremented each threads workload with a lengthy calculation. This
did the trick to show the time slicing in action. The first sort
thread fired and worked for about 3 seconds, then the others kicked
in. :-) Very different to Windows.
Regards,
- Graeme -
On 02/10/06, Pete Cervasio <cervasio at airmail.net> wrote:
> On Friday 29 September 2006 04:57, Graeme Geldenhuys wrote:
> >
> > Below is a text (console) thread demo. The one thread counts from 0 to
> > 1k and the other thread counts down from 1k to 0. Again, under Linux,
> > one thread executes and teminates, then the next thread executes and
> > terminates.
>
> Greetings, Graeme.
>
> I think I see the problem. On today's fast machines, a count of 1000 just
> isn't enough processing for a meaningful test, at least not under Linux. I
> really don't know much about Windows, but my conjecture is that perhaps under
> that system the function calls to write the output cause the other thread to
> receive processing time.
>
> The following modified version of your program shows that threads work under
> Linux. The execute loops have been modified to continually count up/down (as
> appropriate) until terminated. The RunNow procedure was modified to let the
> threads run for three seconds before terminating them itself, and the
> FThreadCount thing was taken out (along with the OnTerminate handlers).
>
> To properly see the output, you should redirect it to a file, unless you
> really have a LOT of scrollback buffer set up. :-) On my Athlon XP 2200 I
> get a file 35.5 megabytes in size!
>
> ~/tmp $./demo1 > demo1.txt
> ~/tmp $ls -l demo1.txt
> -rw-r--r-- 1 pcervasio users 39566886 2006-10-02 12:31 demo1.txt
>
> After looking at the contents of demo1.txt, I can see that the increment
> thread actually got to its eleventh count up before the decrement thread got
> its first share of time. This should help explain why in your original
> program it appeared that one thread was executing to completion before the
> other... it WAS, but only because there wasn't enough to do.
>
> The above was done using version 2.04 of the compiler on a Slackware 10.1
> machine with a 2.4.32 kernel. I appear to get similar results on my 2.6.17.6
> box after copying the executable over (running an Athlon 2600). The
> decrementor first shows up after incrementor loop 15. The redirected output
> file is 53 megabytes, though... much bigger than I expected from the machine
> speed difference alone.
>
> I hope this is helpful.
>
> Best regards,
> Pete C.
>
> ---------------------------------------
>
> program demo1a;
>
> {$mode objfpc}{$H+}
>
> uses
> {$IFDEF UNIX}
> {$IFDEF UseCThreads}
> cthreads,
> {$ENDIF}
> {$ENDIF}
> Classes, SysUtils;
>
> type
> // counts up till 1k until terminated
> TIncrementer = class(TThread)
> protected
> procedure Execute; override;
> end;
>
> // counts down from 1k until terminated
> TDecrementer = class(TThread)
> protected
> procedure Execute; override;
> end;
>
> TRunThreads = class(TObject)
> private
> t1, t2: TThread;
> public
> constructor Create;
> procedure RunNow;
> end;
>
>
> { TRunThreads }
>
> constructor TRunThreads.Create;
> begin
>
> t1 := TIncrementer.Create(True);
> t1.Priority := tpLower;
> t1.FreeOnTerminate := True;
>
> t2 := TDecrementer.Create(True);
> t2.Priority := tpLower;
> t2.FreeOnTerminate := True;
> end;
>
>
> procedure TRunThreads.RunNow;
> var
> donetime: TDateTime;
> begin
> { run for 3 seconds }
> donetime := now + encodetime(0, 0, 3, 0);
> writeln('RunNow');
> t1.Resume;
> t2.Resume;
> repeat
> sleep (100);
> until now > donetime;
> t1.terminate;
> t2.terminate;
> sleep (10); { give threads a chance to end }
> WriteLn('All threads completed!');
> end;
>
> { TIncrementer }
>
> procedure TIncrementer.Execute;
> var
> i, j: integer;
> begin
> j := 0;
> while not terminated do
> begin
> writeln (ClassName, ': --- Loop ', j);
> for i := 0 to 1000 do
> begin
> if terminated then break;
> Writeln(Classname, ': ', i);
> end;
> end;
> end;
>
> { TDecrementer }
>
> procedure TDecrementer.Execute;
> var
> i, j: integer;
> begin
> j := 0;
> while not terminated do
> begin
> writeln (ClassName, ': --- Loop ', j);
> for i := 1000 downto 0 do
> begin
> if terminated then break;
> Writeln(Classname, ': ', i);
> end;
> end;
> end;
>
>
> var
> lRunThreads: TRunThreads;
>
> begin
> lRunThreads := TRunThreads.Create;
> lRunThreads.RunNow;
> writeln('Done...');
> end.
>
> ---------------------------------------
> _______________________________________________
> fpc-pascal maillist - fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
--
There's no place like 127.0.0.1
More information about the fpc-pascal
mailing list