【问题标题】:Magic bitboards not speeding up chess engine魔术位板没有加速国际象棋引擎
【发布时间】:2021-10-14 12:09:46
【问题描述】:

我是编写国际象棋引擎的新手,但最近刚刚完成了我的第一个程序。但是它运行缓慢,所以我切换到位板,现在切换到魔术位板。我经常使用国际象棋编程维基。

我现在正在尝试测试位置和 perft 函数,以查看程序每秒可以计算多少个节点(包括批量计数)。现在我的 perft 函数设置为仅计算伪合法移动,并且我已将 make_move 函数设置为不切换转弯。所以我可以用perft来分析R7/8/8/8/8/8/8/8 w - - 的位置。

然而,我的问题是,如果没有魔法位板,我每秒会获得 622 万个节点,而我只能获得 6.29 个节点。看来我的魔法位板不能正常工作。直觉上感觉魔位板的加速应该要大很多。此外,95% 的计算时间都花在了我的伪合法移动生成器上。

正如我所提到的,我是国际象棋引擎的新手,尤其是魔术位板。我不知道如何正确完成查找表,现在我有一个 64*8192 条目的表(用于车)。我在程序开始时通过计算每个方格的所有不同的阻滞剂组合来初始化这个表。然后我的索引由 (occ >> (64-13))+8192 * square 给出,以免表条目重叠。 (来自https://www.chessprogramming.org/Magic_Bitboards)。

我的魔法位板速度慢的原因是我巨大的桌子尺寸吗?还有其他更有效的方法吗?

速度提升如此之小的原因完全有可能是因为时间不是花在生成动作上,而是在不同位板上的位上进行迭代。有没有办法加快这个过程?似乎(通过一些谷歌搜索)我的功能

int ls1b(u64 bitboard) {
    if (bitboard) {
        return count((bitboard & -bitboard) - 1);
    }
    return -1;
}

int count(u64 bitboard) {
    int count = 0;
    while(bitboard) {
        count++;
        bitboard &= bitboard - 1;
    }
    return count;
}

尽可能快。 stockfish(或其他 c++ 引擎)如何进行这种迭代?

【问题讨论】:

  • 你需要一个好的分析器——仅仅猜测你的程序为什么慢是没有用的。
  • 你能推荐任何好的c++代码分析器@500-InternalServerError吗?
  • 这将是题外话 - 除了我不知道你的平台。
  • 我在 Windows 上,但我也有一台 linux 计算机,如果这对我有帮助的话。我应该发布一个新问题然后@500-InternalServerError?
  • 寻求建议通常与 SO 无关,因为不可能有正确的答案。

标签: c++ chess


【解决方案1】:

我无法评论你程序的其余部分,因为我看不到它,但至于你的位功能,它们可以改进,见:

https://www.chessprogramming.org/BitScan#Trailing_Zero_Count https://en.wikipedia.org/wiki/Hamming_weight

int lsb(uint64_t bb) {
   static const int lookup67[67+1] = {
      64,  0,  1, 39,  2, 15, 40, 23,
       3, 12, 16, 59, 41, 19, 24, 54,
       4, -1, 13, 10, 17, 62, 60, 28,
      42, 30, 20, 51, 25, 44, 55, 47,
       5, 32, -1, 38, 14, 22, 11, 58,
      18, 53, 63,  9, 61, 27, 29, 50,
      43, 46, 31, 37, 21, 57, 52,  8,
      26, 49, 45, 36, 56,  7, 48, 35,
       6, 34, 33, -1 };
   return lookup67[(bb & -bb) % 67];
}

const uint64_t m1  = 0x5555555555555555; //binary: 0101...
const uint64_t m2  = 0x3333333333333333; //binary: 00110011..
const uint64_t m4  = 0x0f0f0f0f0f0f0f0f; //binary:  4 zeros,  4 ones ...
const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...

int count(uint64_t x)
{
    x -= (x >> 1) & m1;             //put count of each 2 bits into those 2 bits
    x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits 
    x = (x + (x >> 4)) & m4;        //put count of each 8 bits into those 8 bits 
    return (x * h01) >> 56;  //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ... 
}

【讨论】:

    猜你喜欢
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    相关资源
    最近更新 更多