c – 随机存储器访问是否昂贵?

在优化我的连接四游戏引擎期间,我达到了一个点,其中进一步的改进只能是最小的,因为在下面的代码示例中,指令TableEntry te = mTab​​le [idx i]使用了大部分cpu时间.
TableEntry getTableEntry(unsigned __int64 lock)
{
    int idx = (lock & 0xFFFFF) * BUCKETSIZE;
    for (int i = 0; i < BUCKETSIZE; i++)
    {
        TableEntry te = mTable[idx + i]; // bottleneck,about 35% of cpu usage
        if (te.height == NOTSET || lock == te.lock)
            return te;
    }
    return TableEntry();
}

哈希表mTable被定义为std :: vector< TableEntry>并且有大约4.2密耳.托管(约64 MB).我试图通过在没有速度改进的情况下分配新表来替换vector.

我怀疑随机访问内存(因为Zobrist Hashing功能)可能很昂贵,但真的那么多?你有改进功能的建议吗?

谢谢!

编辑:BUCKETSIZE的值为4.它用作collision strategy.一个TableEntry的大小是16字节,结构如下所示:

struct TableEntry
{                                       // Old New
    unsigned __int64 lock;              //   8   8
    enum { VALID,UBOUND,LBOUND }flag; //   4   4
    short score;                        //   4   2
    char move;                          //   4   1
    char height;                        //   4   1
                                        // -------
                                        //  24  16 Bytes
    TableEntry() : lock(0LL),flag(VALID),score(0),move(0),height(-127) {}
};

摘要:该功能最初需要39秒.在进行jdehaan建议的更改后,该功能现在需要33秒(程序在100秒后停止).它更好,但我认为Konrad Rudolph是正确的,并且缓慢失误的主要原因是缓慢.

解决方法

关于复制TableEntry的观点是有效的.但是让我们来看看这个问题:

I SUSPECT that accessing the memory randomly (…) Could be expensive,but really that much?

总之,是的.

使用您的大小的数组进行随机内存访问是缓存杀手.它会产生大量缓存未命中,比缓存中的内存访问速度快7000倍.三个数量级 – 这是1000倍.

另一方面,它实际上看起来好像你按顺序使用了很多数组元素,即使你使用哈希生成起点.这反映了缓存未命中理论,除非你的BUCKETSIZE很小并且代码经常使用来自外部的不同锁定值来调用.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...