Ejemplo n.º 1
0
 internal static void init()
 {
     for (int i = 0; i < Constants.BROKER_SLOTS; i++)
     {
         _pool[i] = new MovePicker[0];
     }
 }
Ejemplo n.º 2
0
        internal static void Free(MovePicker obj)
        {
            obj.Recycle();
#if WINDOWS_RT
            _cnt[Environment.CurrentManagedThreadId & Constants.BROKER_SLOT_MASK]--;
#else
            _cnt[System.Threading.Thread.CurrentThread.ManagedThreadId & Constants.BROKER_SLOT_MASK]--;
#endif
        }
Ejemplo n.º 3
0
        /// Constructors of the MovePicker class. As arguments we pass information
        /// to help it to return the presumably good moves first, to decide which
        /// moves to return (in the quiescence search, for instance, we only want to
        /// search captures, promotions and some checks) and about how important good
        /// move ordering is at the current node.
        internal void MovePickerC(Position p, Move ttm, Depth d, History h,
                                  Stack ss, Value beta, MovePicker mpExt)
        {
            pos        = p;
            H          = h;
            depth      = d;
            mpExternal = mpExt;

            Debug.Assert(d > DepthC.DEPTH_ZERO);

            captureThreshold  = 0;
            curMovePos        = lastMovePos = 0;
            lastBadCapturePos = Constants.MAX_MOVES - 1;

            recaptureSquare = 0;
            lastQuietPos    = 0;
            mpos            = 0;

            if (p.in_check())
            {
                phase = SequencerC.EVASION;
            }
            else
            {
                phase = SequencerC.MAIN_SEARCH;

                ms[Constants.MAX_MOVES].move     = ss.killers0;
                ms[Constants.MAX_MOVES + 1].move = ss.killers1;

                // Consider sligtly negative captures as good if at low depth and far from beta
                if (ss.eval < beta - Constants.PawnValueMidgame && d < 3 * DepthC.ONE_PLY)
                {
                    captureThreshold = -Constants.PawnValueMidgame;
                }

                // Consider negative captures as good if still enough to reach beta
                else if (ss.eval > beta)
                {
                    captureThreshold = beta - ss.eval;
                }
            }

            ttMove       = (ttm != 0 && pos.is_pseudo_legal(ttm) ? ttm : MoveC.MOVE_NONE);
            lastMovePos += ((ttMove != MoveC.MOVE_NONE) ? 1 : 0);
        }
Ejemplo n.º 4
0
        internal static MovePicker GetObject()
        {
#if WINDOWS_RT
            int slotID = Environment.CurrentManagedThreadId & Constants.BROKER_SLOT_MASK;
#else
            int slotID = System.Threading.Thread.CurrentThread.ManagedThreadId & Constants.BROKER_SLOT_MASK;
#endif
            if (_cnt[slotID] == _pool[slotID].Length)
            {
                int          poolLength = _pool[slotID].Length;
                MovePicker[] temp       = new MovePicker[poolLength + Constants.BrokerCapacity];
                Array.Copy(_pool[slotID], temp, poolLength);
                for (int i = 0; i < Constants.BrokerCapacity; i++)
                {
                    temp[poolLength + i] = new MovePicker();
                }
                _pool[slotID] = temp;
            }
            return(_pool[slotID][_cnt[slotID]++]);
        }
Ejemplo n.º 5
0
        // split() does the actual work of distributing the work at a node between
        // several available threads. If it does not succeed in splitting the node
        // (because no idle threads are available, or because we have no unused split
        // point objects), the function immediately returns. If splitting is possible, a
        // SplitPoint object is initialized with all the data that must be copied to the
        // helper threads and then helper threads are told that they have been assigned
        // work. This will cause them to instantly leave their idle loops and call
        // search(). When all threads have returned from search() then split() returns.
        internal static Value split(bool Fake, Position pos, Stack[] ss, int ssPos, Value alpha, Value beta,
                                    Value bestValue, ref Move bestMove, Depth depth, Move threatMove,
                                    int moveCount, MovePicker mp, int nodeType)
        {
            Debug.Assert(pos.pos_is_ok());
            Debug.Assert(bestValue > -ValueC.VALUE_INFINITE);
            Debug.Assert(bestValue <= alpha);
            Debug.Assert(alpha < beta);
            Debug.Assert(beta <= ValueC.VALUE_INFINITE);
            Debug.Assert(depth > DepthC.DEPTH_ZERO);

            Thread master = pos.this_thread();

            if (master.splitPointsCnt >= Constants.MAX_SPLITPOINTS_PER_THREAD)
            {
                return(bestValue);
            }

            // Pick the next available split point from the split point stack
            SplitPoint sp = master.splitPoints[master.splitPointsCnt];

            sp.parent     = master.curSplitPoint;
            sp.master     = master;
            sp.cutoff     = false;
            sp.slavesMask = 1UL << master.idx;
#if ACTIVE_REPARENT
            sp.allSlavesRunning = true;
#endif

            sp.depth      = depth;
            sp.bestMove   = bestMove;
            sp.threatMove = threatMove;
            sp.alpha      = alpha;
            sp.beta       = beta;
            sp.nodeType   = nodeType;
            sp.bestValue  = bestValue;
            sp.mp         = mp;
            sp.moveCount  = moveCount;
            sp.pos        = pos;
            sp.nodes      = 0;
            sp.ss         = ss;
            sp.ssPos      = ssPos;

            Debug.Assert(master.is_searching);
            master.curSplitPoint = sp;

            int slavesCnt = 0;

            ThreadHelper.lock_grab(sp.Lock);
            ThreadHelper.lock_grab(splitLock);

            for (int i = 0; i < size() && !Fake; ++i)
            {
                if (threads[i].is_available_to(master))
                {
                    sp.slavesMask           |= 1UL << i;
                    threads[i].curSplitPoint = sp;
                    threads[i].is_searching  = true; // Slave leaves idle_loop()

                    if (useSleepingThreads)
                    {
                        threads[i].wake_up();
                    }

                    if (++slavesCnt + 1 >= maxThreadsPerSplitPoint) // Master is always included
                    {
                        break;
                    }
                }
            }

            master.splitPointsCnt++;

            ThreadHelper.lock_release(splitLock);
            ThreadHelper.lock_release(sp.Lock);

            // Everything is set up. The master thread enters the idle loop, from which
            // it will instantly launch a search, because its is_searching flag is set.
            // We pass the split point as a parameter to the idle loop, which means that
            // the thread will return from the idle loop when all slaves have finished
            // their work at this split point.
            if (slavesCnt != 0 || Fake)
            {
                master.idle_loop(sp, null);
                // In helpful master concept a master can help only a sub-tree of its split
                // point, and because here is all finished is not possible master is booked.
                Debug.Assert(!master.is_searching);
            }

            // We have returned from the idle loop, which means that all threads are
            // finished. Note that setting is_searching and decreasing activeSplitPoints is
            // done under lock protection to avoid a race with Thread::is_available_to().
            ThreadHelper.lock_grab(sp.Lock); // To protect sp->nodes
            ThreadHelper.lock_grab(splitLock);

            master.is_searching = true;
            master.splitPointsCnt--;
            master.curSplitPoint = sp.parent;
            pos.nodes           += sp.nodes;
            bestMove             = sp.bestMove;

            ThreadHelper.lock_release(splitLock);
            ThreadHelper.lock_release(sp.Lock);

            return(sp.bestValue);
        }
Ejemplo n.º 6
0
        internal static void Warmup()
        {
            // Bench 128 4 17 yields:

            // CheckInfoBroker: 140 (4/32/40/32/32)
            // EvalInfoBroker: 16 (4/4/4/4)
            // SwapListBroker: 16 (4/4/4/4)
            // MovesSearchedBroker: 120 (28/36/28/28)
            // PositionBroker: 32 (8/8/8/8)
            // StateInfoArrayBroker: 16 (4/4/4/4)

            // MListBroker: 20 (4/4/4/4/4)
            // LoopStackBroker: 32 (8/8/8/8)
            // MovePickerBroker: 136 (32/40/32/32)
            // StateInfoBroker: 132 (32/36/32/32)

            // Specific allocation not to overallocate memory for nothing
            int i, brokerSize;

            // Reusing brokers
            brokerSize = 40; for (i = 0; i < brokerSize; i++)
            {
                CheckInfoBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                CheckInfoBroker.Free();
            }
            brokerSize = 4; for (i = 0; i < brokerSize; i++)
            {
                EvalInfoBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                EvalInfoBroker.Free();
            }
            brokerSize = 4; for (i = 0; i < brokerSize; i++)
            {
                SwapListBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                SwapListBroker.Free();
            }
            brokerSize = 36; for (i = 0; i < brokerSize; i++)
            {
                MovesSearchedBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                MovesSearchedBroker.Free();
            }
            brokerSize = 8; for (i = 0; i < brokerSize; i++)
            {
                PositionBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                PositionBroker.Free();
            }
            brokerSize = 4; for (i = 0; i < brokerSize; i++)
            {
                StateInfoArrayBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                StateInfoArrayBroker.Free();
            }
            brokerSize = 4; for (i = 0; i < brokerSize; i++)
            {
                MListBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                MListBroker.Free();
            }
            brokerSize = 36; for (i = 0; i < brokerSize; i++)
            {
                StateInfoBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                StateInfoBroker.Free();
            }

            // Recycling brokers
            brokerSize = 8; LoopStack[] arrLoopStack = new LoopStack[brokerSize]; for (i = 0; i < brokerSize; i++)
            {
                arrLoopStack[i] = LoopStackBroker.GetObject();
            }
            for (i = brokerSize - 1; i >= 0; i--)
            {
                LoopStackBroker.Free(arrLoopStack[i]);
            }
            brokerSize = 40; MovePicker[] arrMovePicker = new MovePicker[brokerSize]; for (i = 0; i < brokerSize; i++)
            {
                arrMovePicker[i] = MovePickerBroker.GetObject();
            }
            for (i = brokerSize - 1; i >= 0; i--)
            {
                MovePickerBroker.Free(arrMovePicker[i]);
            }
        }
Ejemplo n.º 7
0
 public void Recycle()
 {
     pos        = null;
     H          = null;
     mpExternal = null;
 }