鲲鹏社区首页
中文
注册
开发者
我要评分
获取效率
正确性
完整性
易理解
在线提单
论坛求助

围绕流程,同时访问的数据邻近定义,提高数据访问效率

【说明】 一般来说,需要统筹考虑指令执行过程与数据组织形式之间的关系,做到单个流程执行过程中可能连续访问的数据在内存空间上聚拢,确保D-Cache加速效果。

具体地,可以考虑,在数据结构中将频繁访问的数据字段定义在靠前,较少访问的数据字段定义靠后,这样大部分的访问时只需要加载一次Cache就完成处理,否则要加载多次;提取的热点结构体中字段赋值使用set函数进行封装,确保与非热点字段同时赋值,避免遗漏。

【原理】 现代CPU硬件系统中,大都存在CPU片内Cache,在CPU尝试读取数据时,会优先将目标地址的邻近区域加载到D-Cache(数据Cache)中,在后续指令读取临近数据时,优先从Cache中读取,提升CPU执行效率;但是如果访问的数据在内存空间上跨度较大,可能导致D-Cache被反复替换(重复Load Cache),从而导致性能恶化;

【注意事项】 数据结构的定义(建模)是面向业务场景/功能的结构化表现,围绕流程重新排布数据可能导致数据建模的受到影响,因此需要在软件的可维护性和性能表现之间做好权衡。

【案例】

优化前
struct KeyValueList {
    int keys[0x100];
    int values[0x100];
};

int FuncCheckKeyValuePairExist(KeyValueList *origData, int keyExpected, int valueExpected) 
{
    int index;
    for (index = 0; index < 0x100; index++) {
        if (origData->keys[index] == keyExpected && origData->values[index] == valueExpected) {
            return 1;
        }
    }
    return 0;
}

说明:上述函数FuncCheckKeyValuePairExist中,在进行for循环查找(keyExpected, valueExpected)对时,循环每轮访问origData时都会连续访问keys和values中两个间隔较远的数据,导致D-Cache重新装载,效率低下。

优化后
struct KeyValuePair {
    int key;
    int value;
};

struct KeyValueList {
    KeyValuePair pairs[0x100];
};

int FuncCheckKeyValuePairExist(KeyValueList *origData, int keyExpected, int valueExpected) 
{
    int index;
    for (index = 0; index < 0x100; index++) {
        if (origData.pairs[index].key == keyExpected && origData.pairs[index].value == valueExpected) {
            return 1;
        }
    }
    return 0;
}

说明:经过对KeyValueList数据结构的重新设计,使得每次连续访问的key和value连续存放,提高D-Cache命中率。