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

将不同业务流程中读写的数据分开定义,消减伪共享

【说明】 频繁读操作,写操作的数据,避免组织在一起,以避免Cache伪共享。

【原理】 核环境下,cache机制的同步单元是Cache Line(典型场景下为64字节),不同核并发执行时,同一个数据结构的不同字段进行被不同核读写时,可能因为另外某一个核上执行的任务数据写入,导致其他核的Cache被重新加载(强一致性缓存体系更容易发生此类问题),从而导致访存效率降低,这种现象被称为伪共享。

如下图举例:连续定义的8个long类型(占8个字节)字段a,b,c,d,e,f,g,h,其数据分别在CPU核1和核2上访存:核1读取字段c,核2对字段d进行修改,此时可能因核2对字段d的修改,触发核1的cache重加载。

因此,多核环境下,合理定义数据结构,将可能在不同核上并发执行的不同流程中访问的数据分开定义,可以避免伪共享的发生。

【注意事项】 对于线程间共享数据的重新调整,可能影响软件实现的结构化,从而软件建模带来影响;另外,如果采用数据填充等方式对齐Cacheline则可能导致额外的内存开销。

【案例】

优化前
typedef struct{
    int read1;
    int write1;
    int read2;
    int write2;
}DemoStru;

说明:多核场景下,频繁读写的数据位于同一个CacheLine,会导致的CacheMiss,造成性能较低。

优化后
typedef struct{
    int read1;
    int read2;
}DemoStructRead __attribute__((aligned(CACHE_LINE_SIZE)));

typedef struct{
    int write1;
}DemoStructWrite1 __attribute__((aligned(CACHE_LINE_SIZE)));

typedef struct{
    int write2;
}DemoStructWrite2 __attribute__((aligned(CACHE_LINE_SIZE)));

说明:频繁读的成员放在一起,独占一个CacheLine, 频繁写的成员放一起,独占一个CacheLine,以空间换时间。