我想知道是否有可能修改C中没有多线程的现有国际象棋引擎,以便能够支持多线程。我没有这方面的经验,也很感激一些指导。
编辑:更具体一点,我可以添加到我的negamax实现中以使其与多线程兼容吗? :
static double alphaBetaMax(double alpha, double beta, int depthleft, game_t game, bool player)
{
move_t *cur;
move_t *tmp;
double score = 0;
bool did_move = false;
cur = getAllMoves(game, player);
if(cur == NULL) /*/ check mate*/
return -9999999*(player*2-1);
tmp = firstMove;
firstMove = 0;
while (cur != NULL)
{
game_t copy;
if(depthleft<=0 && !isCapture(game, cur)) { /* Quiescence search */
cur = cur->next;
continue;
}
did_move = true;
copyGame(game, ©);
makeMove(©, *cur);
firstMove = NULL;
score = -alphaBetaMax(-beta, -alpha, depthleft - 1, copy, !player);
if(board_count > MAX_BOARDS)
break;
freeGame(copy);
if(score > alpha)
alpha = score;
if (beta <= alpha)
break;
cur = cur->next;
}
firstMove=tmp;
freeMoves();
if(!did_move)
alpha = evaluate(game)*(player*2-1);
return alpha;
}
答案 0 :(得分:2)
快速国际象棋引擎依赖于两件事:缓存位置评估和alpha / beta策略。缓存位置并使其线程安全和快速很难。 alpha / beta策略依赖于看似最好的移动被完全评估之前你开始评估其他移动。这也使得使用多线程变得困难。
初学者作曲家到莫扎特:&#34;你能告诉我如何创作一首交响曲&#34;?莫扎特初学者:&#34;也许在你年轻的时候,你应该先尝试一些比较容易的东西。 &#34;初学者到莫扎特:&#34;但是当你比我现在年轻时,你写了交响曲。 &#34;莫扎特初学者:&#34;是的,但我没有问过任何人&#34;。
答案 1 :(得分:2)
Alpha-Beta修剪本质上是单线程的。使用动态树分裂的变体的成功方法基本上意味着同时搜索各种分支。然而,搜索下一个分支(或beta-cut)的可能性(在经过良好调整的引擎中)通常不会超过内存等待等其他并行性瓶颈。
我建议,首先将搜索修改为&#34;重新搜索&#34;像NegaScout或PVS这样的算法,代码变化很小,会对你现在的纯Alpha-Beta进行很好的改进,然后再调整你的移动顺序以产生有效的beta-cut。 此后,您可以尝试根据beta-cut机会拆分树。通常情况下,当在换位表或杀手移动中发现移动时切断的可能性更高,而在开始搜索不良捕获和安静移动时则更少。
看看CPW对它的一些想法和YBWC算法。 Young Brothers Wait Concept
答案 2 :(得分:0)
我目前正在编写一个c ++国际象棋引擎,我做了一个很简单但不是最佳的解决方案:
在常规搜索功能中,我加入了线程,然后循环浏览结果。
这种方法最有效吗?
目前,我们首先着重于搜索最相关的动作,但最终您会看到所有动作,并且几乎无法深入到一个动作,但是效果很好
易于实现,并且在任何情况下都比“单CPU”搜索更好。即使一招花费更多时间-它仍在一个CPU上运行,就像然后:D
也许从这开始