BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Random and Multithreading
Goto page 1, 2  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Language BASM
View previous topic :: View next topic  
Author Message
John
Guest





PostPosted: Thu Apr 12, 2007 1:38 pm    Post subject: Random and Multithreading Reply with quote



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
Back to top
Les Pawelczyk
Guest





PostPosted: Thu Apr 12, 2007 7:07 pm    Post subject: Re: Random and Multithreading Reply with quote



Quote:
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.


Random function makes use of RandSeed global variable. It modifies it every time it is called. If two different CPUs (cores) modify the same memory at the same time, it will cause cache thrashing and consequently serious slow-down.



Les.
Back to top
John
Guest





PostPosted: Thu Apr 12, 2007 7:40 pm    Post subject: Re: Random and Multithreading Reply with quote



Thanks Les for your reply.

Is there a way to avoid this by using another fast ranndom routines ?
or any other solution ?

Thanks
Back to top
Dan Downs
Guest





PostPosted: Thu Apr 12, 2007 8:05 pm    Post subject: Re: Random and Multithreading Reply with quote

Quote:
Is there a way to avoid this by using another fast ranndom routines ?
or any other solution ?

I haven't looked at the implementation of random, but rolling your own
version that uses a thread local RandSeed variable instead of the global
would probably do it. I'm not sure how that would effect the randomness
though.

DD
Back to top
Les Pawelczyk
Guest





PostPosted: Thu Apr 12, 2007 8:08 pm    Post subject: Re: Random and Multithreading Reply with quote

Quote:
Is there a way to avoid this by using another fast ranndom routines ?
or any other solution ?


Yes, but any such solution would have to incorporate separate RandSeed variable (or variables) per thread in such a way that each of those variables (or sets of variables) would not share same cache lines. Cache lines are currently 64 bytes long and are aligned by 64 bytes. The way to make sure two variables (or sets of variables) are separated by 64 bytes in memory is to make them part of a record or object which is padded with dummy 64 byte long field (array[0..63] of byte for example).



Les.
Back to top
John
Guest





PostPosted: Thu Apr 12, 2007 8:26 pm    Post subject: Re: Random and Multithreading Reply with quote

So one solution would be to "clone" the random function and puting it
directly tin the thread class and using RandSeed as a local variable ?

but I don't see any random function in system.pas
Back to top
John Herbster
Guest





PostPosted: Thu Apr 12, 2007 8:41 pm    Post subject: Re: Random and Multithreading Reply with quote

"John" <NoSpam (AT) NoSpam (DOT) com> wrote
Quote:
here's the result for doing 48000000 randoms
on my core 2 duo:
Normal: 204 ms Multithread (2 threads): 1109 ms.

That is about 48 random numbers per microsecond.

Quote:
- Is there any alternative to RTL random that support
better and faster random?

John,
What are you doing with these pseudo-random
numbers? If you are doing anything sophisticated with
them, I suspect that it must also be taking some time.
If it is not sophisticated, then I suspect that the relation
ship between adjacent numbers is going expose
problems with their lack of true randomness.
Rgds, JohnH
Back to top
John
Guest





PostPosted: Thu Apr 12, 2007 9:04 pm    Post subject: Re: Random and Multithreading Reply with quote

Quote:
here's the result for doing 48000000 randoms
on my core 2 duo:
Normal: 204 ms Multithread (2 threads): 1109 ms.

That is about 48 random numbers per microsecond.

- Is there any alternative to RTL random that support
better and faster random?

John,
What are you doing with these pseudo-random
numbers? If you are doing anything sophisticated with
them, I suspect that it must also be taking some time.


non this bench is the result of the test code that i have put on my
first thread...

only this : for i := 0 to FCount - 1 do
j := random(255);

nothing else....
Back to top
Bob Gonder
Guest





PostPosted: Thu Apr 12, 2007 9:50 pm    Post subject: Re: Random and Multithreading Reply with quote

John Herbster wrote:

Quote:
here's the result for doing 48,000,000 randoms
on my core 2 duo:
Normal: 204 ms Multithread (2 threads): 1109 ms.

That is about 48 random numbers per microsecond.

Let's see...
48 MOPs at 2GHz is about 40 clocks per OP per second
(2,000M / 48M == 41.7 )

Normal runs in 1/5 second, so 8 instructions(clocks) per loop.
Multithread is running at about 44 instructions(clocks) per loop.

How small is the Rand function, and is the "normal" method optimized
better?
TRandom.Execute should call NormalRandom to eliminate optimization
differences.
He might also run it with One thread in addition to Two, to eliminate
differences.


inherited Create(Suspended);
FCount := Count;

FCount should be set before Create is called.

He is including Thread setup/teardown in his timing.
He might have each thread time itself and report.

Have we established that threads are distributed automatically by
Windows? Or do they remain process/processor bound by default?

See GetProcessAffinityMask()
And SetThreadAffinityMask()
And SetThreadIdealProcessor()
Back to top
John
Guest





PostPosted: Thu Apr 12, 2007 10:08 pm    Post subject: Re: Random and Multithreading Reply with quote

Any usefull sample ?
Quote:

See GetProcessAffinityMask()
And SetThreadAffinityMask()
And SetThreadIdealProcessor()

Back to top
John Herbster
Guest





PostPosted: Fri Apr 13, 2007 12:23 am    Post subject: Re: Random and Multithreading Reply with quote

"John" <NoSpam (AT) NoSpam (DOT) com> wrote
Quote:
... I have to apply a graphic filter on a Bitmap ...

John,
I just noticed the above line in your OP. Are you
trying to do dithering to smooth out gradient steps?
If so, I believe that there are better ways to do this
than recomputing the random function each time.
Using a PRNG (pseudo-random number generator)
to do this is often an easy way to find correlations
in the generated random number sequence, which
is usually what you do *not* want when doing image
dithering.
Regards, JohnH
Back to top
Sven Pran
Guest





PostPosted: Fri Apr 13, 2007 1:23 am    Post subject: Re: Random and Multithreading Reply with quote

"John" <NoSpam (AT) NoSpam (DOT) com> wrote in message
news:461e4f99$1 (AT) newsgroups (DOT) borland.com...
Quote:
So one solution would be to "clone" the random function and puting it
directly tin the thread class and using RandSeed as a local variable ?

but I don't see any random function in system.pas

Search System.pas repeatedly for the word RandSeed

regards Sven
Back to top
Bob Gonder
Guest





PostPosted: Fri Apr 13, 2007 5:49 am    Post subject: Re: Random and Multithreading Reply with quote

John wrote:

Quote:
Any usefull sample ?

Not from me.
Don't have multi-cpu, nor Delphi to test.
Those functions look pretty easy to understand though.
Back to top
John
Guest





PostPosted: Fri Apr 13, 2007 8:11 am    Post subject: Re: Random and Multithreading Reply with quote

I have seen Randseen not Random....
Back to top
John
Guest





PostPosted: Fri Apr 13, 2007 8:11 am    Post subject: Re: Random and Multithreading Reply with quote

Quote:
I just noticed the above line in your OP. Are you
trying to do dithering to smooth out gradient steps?


no it's more like an explode filter, for each picel of Destimage you
have (pseudocode) :

Dest.Pixel[x,y]:=scr.Pixel[x + random(A), y + random(b)];
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Language BASM All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.