Random and Multithreading
- From: John <NoSpam@xxxxxxxxxx>
- Date: Thu, 12 Apr 2007 10:38:19 +0200
Hello,
I have to apply a graphic filter on a Bitmap.
I have a corde 2 duo since a few weeks so I decided to port this filter to multithreading, and I was very surprised that it takes more time in multithreading than normal.
After spending some times on my code I have discovered that the bottleneck was the random function.
So i have made a small example that do only random, and i was a lot surpised.
here's the result for doing 48000000 randoms on my core 2 duo :
Normal : 204 ms
Multithread (2 threads) : 1109 ms.
so My questtions are :
- Am I missing something ?
- Is there any alternative to RTL random that support better and faster random ?
here's the code :
Type
TRandom = class(TThread)
private
FCount: Integer;
protected
procedure Execute; override;
public
constructor Create(Count: integer; Suspended: Boolean);
end;
//The threaded random Class
constructor TRandom.Create(Count: integer; Suspended: Boolean);
begin
FreeOnTerminate := False;
inherited Create(Suspended);
FCount := Count;
end;
procedure TRandom.Execute;
var
i, j: integer;
begin
for i := 0 to FCount - 1 do
j := random(255);
end;
//the way it is called
procedure DoRandom(Count: integer; NbThreads: integer);
var
threads: array of THandle;
ft: array of TRandom;
i, j, NBCountThread, Lastthread, NBC: integer;
begin
try
//Number of count per thread
NBCountThread := Count div NbThreads;
Lastthread := NbThreads - 1;
SetLength(threads, NbThreads);
SetLength(ft, NbThreads);
j := 0;
// start all threads
for i := 0 to high(threads) {Lastthread} do
begin
if i < Lastthread then
begin
//Number of count for this thread
NBC := NBCountThread;
inc(j, nbc);
end
else
begin
//Number of count for last thread
NBC := Count - j;
end;
ft[i] := TRandom.Create(NBC, True);
// store handle of the thread so we know what to wait for
threads[i] := ft[i].Handle;
ft[i].Resume;
end;
// wait until all threads are done
WaitForMultipleObjects(NbThreads, @threads[0], true, INFINITE);
finally
for i := 0 to high(ft) do
if Ft[i] <> nil then
FreeAndNil(Ft[i]);
SetLength(ft, 0);
SetLength(Threads, 0);
end;
end;
//the same thing without multithreading
procedure NormalRandom(FCount: integer);
var
i, j: integer;
begin
for i := 0 to FCount - 1 do
j := random(255);
end;
//the test
procedure TForm1.Button2Click(Sender: TObject);
var
TC: integer;
begin
tc := Gettickcount;
NormalRandom(48000000);
tc := Gettickcount - tc;
Showmessage(inttostr(tc));
tc := Gettickcount;
DoRandom(48000000,2); //2 threads
tc := Gettickcount - tc;
Showmessage(inttostr(tc));
end;
thanks
John
.
- Follow-Ups:
- Re: Random and Multithreading
- From: John Herbster
- Re: Random and Multithreading
- From: John Herbster
- Re: Random and Multithreading
- From: Les Pawelczyk
- Re: Random and Multithreading
- Prev by Date: Re: FastMM + DEP + COM+
- Next by Date: Re: FastMM + DEP + COM+
- Previous by thread: FastMM + DEP + COM+
- Next by thread: Re: Random and Multithreading
- Index(es):