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 

Train crash, (index locking)

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Language BASM
View previous topic :: View next topic  
Author Message
Martin James
Guest





PostPosted: Mon Nov 14, 2005 7:48 pm    Post subject: Train crash, (index locking) Reply with quote



I've got this array of pointers and two pointers to this array, one starts
off pointing at the top and the other pointing at the base:

dataArray=array[0..summat-1] of pointer;
...
basePointer:=@dataArray;
topPointer:=@dataArray[summat-1];

Two threads start off on this data, one eating it from the base and the
other from the top, inc-ing and dec-ing the index pointers. Eventually, the
two pointers will meet in the middle and both threads must realise that they
have hit each other with one thread, or the other, having cleanly eaten up
the last data value. The threads inc and dec the pointers via a method
function:

function incLow:boolean;
function decHigh:boolean;

so these functions should return 'true' if a data item is available via. the
changed index pointer, or 'false' if there is no more data.

How can I do this without a critical section? A CS here would be too slow
and inappropriate due to the tightness of the loop and large probability of
contention during the crash.

I should be able to work this out myself but I have a headache from the
multiThreaded sorts. I think I need beer.

Rgds,
Martin


Back to top
Joe Bain
Guest





PostPosted: Mon Nov 14, 2005 8:09 pm    Post subject: Re: Train crash, (index locking) Reply with quote



Martin James wrote:

Quote:
I've got this array of pointers and two pointers to this array, one
starts off pointing at the top and the other pointing at the base:

Do you have to have one going bottom up and the other going top down?

If you pass each thread a begining pointer and an end pointer they may
not need any sort of sync to run.




--------------
Joe Bain
www.iegsoftware.com

Back to top
Les Pawelczyk
Guest





PostPosted: Mon Nov 14, 2005 9:02 pm    Post subject: Re: Train crash, (index locking) Reply with quote



Quote:
How can I do this without a critical section? A CS here would be too slow
and inappropriate due to the tightness of the loop and large probability of
contention during the crash.


The possible solution would be to declare "basePointer" and "topPointer" in such a way as to occupy 8 bytes of contiguous memory (as in packed record for example) and then employing CMPXCHG8B with the LOCK prefix so every time you update one or the other, both of them are locked. Locking is going to be slow nevertheless, but should be faster that critical section.


Les.



Back to top
Martin James
Guest





PostPosted: Mon Nov 14, 2005 9:44 pm    Post subject: Re: Train crash, (index locking) Reply with quote

Quote:

I've got this array of pointers and two pointers to this array, one
starts off pointing at the top and the other pointing at the base:

Do you have to have one going bottom up and the other going top down?

Yes :)

Quote:
If you pass each thread a begining pointer and an end pointer they may
not need any sort of sync to run.

Unfortunately, this is not possible :(

Depending on the data in the array, the actual speed of the two trains is
unknown <g>

It is possible that the data may be such that one thread consumes all the
data and the other thread none.

Basically, there are [number of processors] of these arrays containing data
that has been sorted. The data is then merged into one, large array by two
threads, one taking the overall minimum value from the bottom-up pointers of
these arrays and the other taking the overall max. value from the top-down
pointers. Once a thread has found which array contains the min/max value,
it loads this into the output array and then incs/decs the index of the
array that supplied the value.

It is possible, therefore, that a particular array has only large values and
so the thread that is extracting max. values will use up all the data from
this array before the thread extracting minimum values takes any - that
thread would meanwhile be extracting the small values from the other arrays
because it always finds that the lowest minimum value of all the other
arrays is always less than the minimum value of the array that happens to
contain large values, so it never gets round to extracting any minimums from
that array.

The more sorted the original data, the more likely this is to happen.

Rgds,
Martin



Back to top
Martin James
Guest





PostPosted: Mon Nov 14, 2005 9:46 pm    Post subject: Re: Train crash, (index locking) Reply with quote

Quote:

The possible solution would be to declare "basePointer" and "topPointer"
in such a way as to occupy 8 bytes of contiguous memory (as in packed record

for example) and then employing CMPXCHG8B with the LOCK prefix so every time
you update one or the other, both of them are locked. Locking is going to be
slow nevertheless, but should be faster that critical section.
Quote:


Er.. hmm.. I need beer to think about this :)

Thanks,
Martin



Back to top
Cristian Nicola
Guest





PostPosted: Tue Nov 15, 2005 9:56 am    Post subject: Re: Train crash, (index locking) Reply with quote

Very simple and elegant Very Happy I was about to suggest this option :D

Cristian Nicola

to swap use something like:

function CAS(aDestAddr: pointer; v1: pointer; v2: integer; n1: pointer; n2:
integer): boolean;
asm
push ebx
push esi
mov esi, aDestAddr
mov eax, v1
mov edx, v2
mov ebx, n1
mov ecx, n2
{ LOCK cmpxchg8b qword ptr [esi] }
db $F0,$0F,$C7,$0E
sete result
pop esi
pop ebx
end;

and pass:
aDestAddr : the address of record holding the 2 values
v1: old base
v2: old top
n1: new base
n2: new top

In case of first function new base = old base, new top = old
top -sizeof(pointer)
In case of second function new base = old base + sizeof(pointer), new top =
old top.

"Les Pawelczyk" <les_at_pixelpointpos_dot_com> wrote

Quote:

The possible solution would be to declare "basePointer" and "topPointer"
in such a way as to occupy 8 bytes of contiguous memory (as in packed record

for example) and then employing CMPXCHG8B with the LOCK prefix so every time
you update one or the other, both of them are locked. Locking is going to be
slow nevertheless, but should be faster that critical section.
Quote:


Les.





Back to top
Cristian Nicola
Guest





PostPosted: Tue Nov 15, 2005 10:00 am    Post subject: Re: Train crash, (index locking) Reply with quote

Forgot to important things:
TYourRecord = record
Top: pointer;
Bottom: pointer;
end;

and creating a new record should be 8 byte aligned (so using normal var, or
normal memory allocation functions is NOT enough)...

Cristian Nicola

ps:


{ allocates a 8-byte align node }
function AllocMem8(size: integer): pointer;
var
p: pointer;
begin
result:= nil;
GetMem(p, size + Cool;
if (p = nil) then
exit;
case (integer(p) and $0000000F) of
$0, $8: result:= pointer(integer(p) + Cool;
$4, $C: result:= pointer(integer(p) + 4);
end;
if (result <> nil) then
pointer(pointer(integer(result) - 4)^):= p
else
FreeMem(p);
end;

{ deallocates a 8-byte aligned node }
procedure FreeMem8(var p: pointer);
begin
if (p <> nil) then
begin
FreeMem(pointer(pointer(integer(p) - 4)^));
p:= nil;
end;
end;


"Cristian Nicola" <n_cristian (AT) hotmail (DOT) com> wrote



Back to top
Cristian Nicola
Guest





PostPosted: Tue Nov 15, 2005 10:07 am    Post subject: Re: Train crash, (index locking) Reply with quote

Forgot another thing:
CAS function would return false if the values have changed so the algorithm
should be:
while true do
begin
{ preserve values }
oldtop:= myrec^.top;
oldbottom:= myrec^.bottom;
{ compare the collision }
if oldtop = oldbottom then
begin
{ collision }
break;
end
else
begin
{ move one end }
if cas(myrec, oldtop, oldbottom, oldtop, oldbottom - sizeof(pointer))
then
break;
end;
end;

"Cristian Nicola" <n_cristian (AT) hotmail (DOT) com> wrote

Quote:
Very simple and elegant Very Happy I was about to suggest this option Very Happy



Back to top
Martin James
Guest





PostPosted: Tue Nov 15, 2005 10:51 am    Post subject: Re: Train crash, (index locking) Reply with quote

Thanks everybody!

I will try Les/Cristian 'LOCK CMPXCHG8B', (I remember when opcode mnemonics
were only 3 chars long - now longer than high-level language identifiers).

I was also thinking of Joe's comment.

Down at the pub last night, I thought of a cunning, 'composite' plan that
avoids most of the locking overhead. The thread-manager that runs the
threads can issue a work-request for each 'train' with a count for each
thread that is [half of one array length-1]. Even if both threads then
happen to suck on the same array, they will not be able to reach each other
and crash, so no slow locking is required. When these tasks are both done,
the 'closeness of the trains' in each array is checked. If they are still
all well apart, the tasks re-issue themselves with a count of [half of
smallest closeness-1]. Eventually, the trains in one or more of the arrays
wil be so close that there is no advantage of going through a thread-manager
dispatch cycle again. Both tasks will then be re-issued with an instruction
to continue to completion, but using the slow bus lock mechanism with the
world's longest opcode mnemonic.

Rgds,
Martin


Back to top
Cristian Nicola
Guest





PostPosted: Tue Nov 15, 2005 11:02 am    Post subject: Re: Train crash, (index locking) Reply with quote

Really nice site:

http://faydoc.tripod.com/cpu/index.htm

Cristian

"Martin James" <mjames_falcon (AT) dial (DOT) pipex.com> wrote

Quote:
Thanks everybody!

I will try Les/Cristian 'LOCK CMPXCHG8B', (I remember when opcode
mnemonics
were only 3 chars long - now longer than high-level language identifiers).




Back to top
Martin James
Guest





PostPosted: Tue Nov 15, 2005 1:09 pm    Post subject: Re: Train crash, (index locking) Reply with quote

Thanks very much!

Rgds,
Martin Smile)



Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Language BASM All times are GMT
Page 1 of 1

 
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.