In crafty it won't just help other threads at that split point, it will help other threads that need help at _any_ split point...Pradu wrote:Sometimes it will sometimes it won't. It just turns into another helper thread (only to the other threads at the split point though) when the parent finishes first and has no more work at the split-point.jswaff wrote:How do you know the parent will finish first? I can see why you would want it to finish first, but not how you know it will.bob wrote: As I mentioned, the parent jumps into ThreadWait() and then jumps right back into the search stuff. This lets the parent finish first, return to ThreadWait() and since the current split point has not been completed, the parent then can be used to help the other threads complete their sub-trees...
--
James
DTS and the call stack
Moderators: hgm, Rebel, chrisw
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: DTS and the call stack
Re: DTS and the call stack
Yes, that's probably what he meant. I must've misunderstood him when he said "this let's the parent finish first."Pradu wrote:Sometimes it will sometimes it won't. It just turns into another helper thread (only to the other threads at the split point though) when the parent finishes first and has no more work at the split-point.jswaff wrote:How do you know the parent will finish first? I can see why you would want it to finish first, but not how you know it will.bob wrote: As I mentioned, the parent jumps into ThreadWait() and then jumps right back into the search stuff. This lets the parent finish first, return to ThreadWait() and since the current split point has not been completed, the parent then can be used to help the other threads complete their sub-trees...
--
James
So, it seems the answer to my original question is:
- the parent must "return back up" since its call stack is the only one set up for it.
- if the parent finishes and one or more helpers are still searching, join in and help them out.
Like Hyatt said, that's not "true DTS," but it's close enough.
--
James
Re: DTS and the call stack
That clears it up, I just misunderstood your earlier post when you said "this let's the parent finish first." Makes perfect sense as you just explained it.bob wrote:I don't know it will finish first. But I have to at least handle that case. take the following scenario...jswaff wrote:How do you know the parent will finish first? I can see why you would want it to finish first, but not how you know it will.bob wrote: As I mentioned, the parent jumps into ThreadWait() and then jumps right back into the search stuff. This lets the parent finish first, return to ThreadWait() and since the current split point has not been completed, the parent then can be used to help the other threads complete their sub-trees...
--
James
I start a search with one thread active, three hung in ThreadWait() waiting for work. As soon as I find a good split point by the YBW criterion, I split the current search into four threads and give them each work to do. Three of the threads are already hung in ThreadWait() waiting on work so they charge off immediately. The original thread then calls ThreadWait() which then lets it charge off as the fourth thread doing the search. Now if the first thread finishes first, it still returns to ThreadWait() where other active threads can give it work. If it finishes last, it just cleans up and goes back to the original search TREE struct which had no threads helping it.
Hard to explain, not that hard to make work, but the data structures are somewhat complicated... This way no thread has to stop and wait, they are always in ThreadWait() which instantly gets them new assignments when they re-enter that code...
I like that approach. Tord is doing about the same thing in Viper (using YBW), so I think I will too. Much better than trying to rewrite my search to do "true DTS."
Thanks .. for the paper, Crafty, and for answering my questions.
--
James
-
- Posts: 287
- Joined: Sat Mar 11, 2006 3:19 am
- Location: Atlanta, GA
Re: DTS and the call stack
How does one handle that? What happens if the parent thread T1 picks up a split point S2 for a thread that isn't under its original split point S1 and the rest of the threads at S1 finish the search. Does further search (backing up) at S1 have to wait for the parent thread to finish it's search at S2? Wouldn't this waste time by not doing precious bounds updating for the parent(s) of S1 which might cutoff the search of S2 or improve bounds on S2?bob wrote:In crafty it won't just help other threads at that split point, it will help other threads that need help at _any_ split point...Pradu wrote:Sometimes it will sometimes it won't. It just turns into another helper thread (only to the other threads at the split point though) when the parent finishes first and has no more work at the split-point.jswaff wrote:How do you know the parent will finish first? I can see why you would want it to finish first, but not how you know it will.bob wrote: As I mentioned, the parent jumps into ThreadWait() and then jumps right back into the search stuff. This lets the parent finish first, return to ThreadWait() and since the current split point has not been completed, the parent then can be used to help the other threads complete their sub-trees...
--
James
Re: DTS and the call stack
Yeah, I was thinking the same thing. Seems you could really "hold things up" if the owner goes off helping everyone else out, meanwhile the search he started is complete and he needs to go return the value back up.Pradu wrote:How does one handle that? What happens if the parent thread T1 picks up a split point S2 for a thread that isn't under its original split point S1 and the rest of the threads at S1 finish the search. Does further search (backing up) at S1 have to wait for the parent thread to finish it's search at S2? Wouldn't this waste time by not doing precious bounds updating for the parent(s) of S1 which might cutoff the search of S2 or improve bounds on S2?bob wrote:In crafty it won't just help other threads at that split point, it will help other threads that need help at _any_ split point...Pradu wrote:Sometimes it will sometimes it won't. It just turns into another helper thread (only to the other threads at the split point though) when the parent finishes first and has no more work at the split-point.jswaff wrote:How do you know the parent will finish first? I can see why you would want it to finish first, but not how you know it will.bob wrote: As I mentioned, the parent jumps into ThreadWait() and then jumps right back into the search stuff. This lets the parent finish first, return to ThreadWait() and since the current split point has not been completed, the parent then can be used to help the other threads complete their sub-trees...
--
James
Haven't thought this through completely, but maybe you could signal to the owner that is off helping at another split point that all his helpers are done, so he can gracefully bow out and go clean things up at his own split point.
That way the owner can be productive, and still returns to finish up what he started.
This is getting interesting.
--
James
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: DTS and the call stack
It's simply the way I designed things to work with the data structures. The point is that any thread can work anywhere in the tree, with no problems, since the data structures are replicated at each split point. For example, assuming 4 threads A, B, C and D,Pradu wrote:How does one handle that? What happens if the parent thread T1 picks up a split point S2 for a thread that isn't under its original split point S1 and the rest of the threads at S1 finish the search. Does further search (backing up) at S1 have to wait for the parent thread to finish it's search at S2? Wouldn't this waste time by not doing precious bounds updating for the parent(s) of S1 which might cutoff the search of S2 or improve bounds on S2?bob wrote:In crafty it won't just help other threads at that split point, it will help other threads that need help at _any_ split point...Pradu wrote:Sometimes it will sometimes it won't. It just turns into another helper thread (only to the other threads at the split point though) when the parent finishes first and has no more work at the split-point.jswaff wrote:How do you know the parent will finish first? I can see why you would want it to finish first, but not how you know it will.bob wrote: As I mentioned, the parent jumps into ThreadWait() and then jumps right back into the search stuff. This lets the parent finish first, return to ThreadWait() and since the current split point has not been completed, the parent then can be used to help the other threads complete their sub-trees...
--
James
A and B can split together, then C can help A and D can help B. If A finishes first, it can help B, C, or D no matter where they are in the tree...
Remember I am not doing a full DTS since I kept my recursive search for simplicity reasons. So once A splits with B, C and D, there is no way the tree can be split anywhere _above_ that split point, since nobody can search there until the split point has been finished. So everyone works below that split point, but there can be many split points below that one. In fact, I on occasion have as many as 60-100 active split points in some endings....
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: DTS and the call stack
Remember, once a split is done at ply N, splits can only be done at ply N+1 and beyond. Which means any of 'em are required to complete before we can complete ply N. Think about it for a minute in the context of YBW and it will become clearer...jswaff wrote:Yeah, I was thinking the same thing. Seems you could really "hold things up" if the owner goes off helping everyone else out, meanwhile the search he started is complete and he needs to go return the value back up.Pradu wrote:How does one handle that? What happens if the parent thread T1 picks up a split point S2 for a thread that isn't under its original split point S1 and the rest of the threads at S1 finish the search. Does further search (backing up) at S1 have to wait for the parent thread to finish it's search at S2? Wouldn't this waste time by not doing precious bounds updating for the parent(s) of S1 which might cutoff the search of S2 or improve bounds on S2?bob wrote:In crafty it won't just help other threads at that split point, it will help other threads that need help at _any_ split point...Pradu wrote:Sometimes it will sometimes it won't. It just turns into another helper thread (only to the other threads at the split point though) when the parent finishes first and has no more work at the split-point.jswaff wrote:How do you know the parent will finish first? I can see why you would want it to finish first, but not how you know it will.bob wrote: As I mentioned, the parent jumps into ThreadWait() and then jumps right back into the search stuff. This lets the parent finish first, return to ThreadWait() and since the current split point has not been completed, the parent then can be used to help the other threads complete their sub-trees...
--
James
Haven't thought this through completely, but maybe you could signal to the owner that is off helping at another split point that all his helpers are done, so he can gracefully bow out and go clean things up at his own split point.
That way the owner can be productive, and still returns to finish up what he started.
This is getting interesting.
--
James
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: DTS and the call stack
More than welcome. It's an interesting project to get this to work right where everyone helps everyone and it scales to a reasonable number of processors (at least 8, preferably beyond, I've run on 16 and 32 with good results)...jswaff wrote:That clears it up, I just misunderstood your earlier post when you said "this let's the parent finish first." Makes perfect sense as you just explained it.bob wrote:I don't know it will finish first. But I have to at least handle that case. take the following scenario...jswaff wrote:How do you know the parent will finish first? I can see why you would want it to finish first, but not how you know it will.bob wrote: As I mentioned, the parent jumps into ThreadWait() and then jumps right back into the search stuff. This lets the parent finish first, return to ThreadWait() and since the current split point has not been completed, the parent then can be used to help the other threads complete their sub-trees...
--
James
I start a search with one thread active, three hung in ThreadWait() waiting for work. As soon as I find a good split point by the YBW criterion, I split the current search into four threads and give them each work to do. Three of the threads are already hung in ThreadWait() waiting on work so they charge off immediately. The original thread then calls ThreadWait() which then lets it charge off as the fourth thread doing the search. Now if the first thread finishes first, it still returns to ThreadWait() where other active threads can give it work. If it finishes last, it just cleans up and goes back to the original search TREE struct which had no threads helping it.
Hard to explain, not that hard to make work, but the data structures are somewhat complicated... This way no thread has to stop and wait, they are always in ThreadWait() which instantly gets them new assignments when they re-enter that code...
I like that approach. Tord is doing about the same thing in Viper (using YBW), so I think I will too. Much better than trying to rewrite my search to do "true DTS."
Thanks .. for the paper, Crafty, and for answering my questions.
--
James
Re: DTS and the call stack
Bob, I'm missing something. In your DTS paper you describe in great detail how important it is to choose a good split point. Manohararajah's thesis talks about a global split point list that is consulted by an idle thread before it sends the HELP message.bob wrote: Remember I am not doing a full DTS since I kept my recursive search for simplicity reasons. So once A splits with B, C and D, there is no way the tree can be split anywhere _above_ that split point, since nobody can search there until the split point has been finished. So everyone works below that split point, but there can be many split points below that one. In fact, I on occasion have as many as 60-100 active split points in some endings....
You don't appear to be doing that. You check a couple of simple conditions, then go right into Thread( ) after the first move is searched. In Thread( ) it looks like you immediately try to launch a parallel search.
So, what am I missing? You seem to be doing more of a YBW search. (I'm looking at Crafty 19.8.)
--
James
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: DTS and the call stack
That's correct. But let's back up a bit. In the late 70's and early 80's the best parallel search algorithm was called "PVS" (for principle variation search). There all the processors always "stuck together" and worked at the same split point. The idea was to step down in the tree following the left-most (or PV) nodes until some satisfactory depth was reached, then the tree was split at that point. Once every branch there was searched in parallel (and as processors ran out of moves to search they just dropped into an idle state) then the entire "wad" of processors backed up one ply and split there. Until you landed at the root and split there.jswaff wrote:Bob, I'm missing something. In your DTS paper you describe in great detail how important it is to choose a good split point. Manohararajah's thesis talks about a global split point list that is consulted by an idle thread before it sends the HELP message.bob wrote: Remember I am not doing a full DTS since I kept my recursive search for simplicity reasons. So once A splits with B, C and D, there is no way the tree can be split anywhere _above_ that split point, since nobody can search there until the split point has been finished. So everyone works below that split point, but there can be many split points below that one. In fact, I on occasion have as many as 60-100 active split points in some endings....
You don't appear to be doing that. You check a couple of simple conditions, then go right into Thread( ) after the first move is searched. In Thread( ) it looks like you immediately try to launch a parallel search.
So, what am I missing? You seem to be doing more of a YBW search. (I'm looking at Crafty 19.8.)
--
James
The problem was all the accumulated idle time when everyone was waiting on the last processor to search the last move at a split point.
DTS broke with this tradition with the "ants at a picnic" type approach where anybody could help anybody anywhere. DTS went a lot further since Cray Blitz was non-recursive, which gave it a lot of flexibility in choosing a split point since whenever an idle processor wanted to help, it could look at the state of the tree for all busy processors and pick the best/most-promising place to split.
Crafty uses the YBW type approach, which is still pretty good at choosing split points since we have to search one move at a node before doing any parallel searching. Most of the time if I get a fail high, it is on the first branch, meaning that the YBW approach does pretty well overall. But one thing the crafty approach does is that there is no requirement that all processors "stick together". A can help B, and if B finishes its part first, it can help A finish up its part, and so forth. So there is very little wait time, which is why the idle time is so very low in Crafty's search threads and why the NPS scales so well. NPS won't scale well if threads are not doing useful work...
So Crafty has a little of DTS, and a YBW flavor to boot...