我想尝试大规模并行国际象棋计算。从我在wiki中看到和理解的和一些引擎的源代码来看,在min-max(negamax,alpha-beta,...)算法的大多数(全部?)实现中,有一个内部位置被更新为每个新的分支,然后在收到对该分支的评估后撤消。
与仅生成新的位置对象并将其传递给下一个分支相比,该技术有哪些好处? 这就是我在之前的引擎中所做的,我相信这种方法在并行性方面更胜一筹。
答案 0 :(得分:1)
您的问题的答案在很大程度上取决于几个因素,例如您如何存放国际象棋棋盘,以及您的制作/取消移动功能的样子。我确信有一些方法可以存储更适合你的方法的电路板,而且历史上一些顶级分层的国际象棋引擎(特别是狡猾的)曾经使用过这种方法,但你说现代引擎不再正确这样做。以下是关于这一点的讨论的链接:
如果你想了解这是为什么,那么你必须了解今天的引擎如何代表董事会。标准实现围绕位板,除了一起使用的冗余邮箱(非计算机国际象棋术语中的数组)之外,每个位置需要12-64位整数。复制所有这些通常比 好 makeMove / unMakeMove函数更贵。
我还想指出混合方法也很常见。通常在棋盘上使用make和unmake,其中像pass passant square和castle权利这样的其他信息会像你建议的那样复制和更改。
答案 1 :(得分:1)
有趣的是,对于<〜300字节的木板表示,在每次移动时(在现代x86上)复制木板都比进行或不进行移动便宜。
正如您所建议的那样,每一步复制电路板的不变特性是从编程角度出发的,包括并行化,非常吸引人。
我的董事会代表是208个字节。用g ++ 7.4.0编译的C ++。
经验表明,木板复制比移动/未复制移动速度快20%。我假设代码使用32/64字节宽的AVX指令进行复制。从理论上讲,每个周期可以复制32/64字节。
只为您:https://github.com/rolandpj1968/oom-skaak/tree/init-impl-legal-move-gen-move-do-undo-2