中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助
鲲鹏小智

预取

正如前面对CPU缓存的介绍,对于存放在内存中的数据,CPU处理相关数据一般需要先从内存取数据到L3,再从L3取数据到L2,再从L2取数据到L1,最后将L1中的数据取到寄存器中,这时候CPU才能对相关数据进行处理。如果CPU下一次需要处理的数据都在L1中,显然这样程序的性能会优于数据都在内存中。而对于预取来说,又可以分为硬件预取和软件预取两种。硬件预取指的由硬件根据访存的历史信息,对未来可能的访存单元预先取入Cache,从而在数据真正被用到时不会造成Cache失效,具有通用性。而软件预取是指程序员通过在业务代码中编写预取指令,对特定位置进行预取,具有针对性。

本文只要介绍基于鲲鹏平台进行编程,故只介绍软件预取。

软件预取

软件预取是通过预取指令实现的,不同架构提供的预取指令也不一样。在鲲鹏平台上,预取指令格式通常如下:

PRFM prfop, [Xn|SP{, #pimm}]

prfop由type<target><policy>三部分组成。

  • type可选模式有:
    • PLD:数据预加载
    • PLI:指令预取
    • PST:数据预存储
  • <target>可选模式有:
    • L1
    • L2
    • L3

    分别表示对三个不同的Cache层级进行操作。

  • <policy>可选模式有:
    • KEEP:数据预取使用后保存一定时间,适用于数据多次使用的场景。
    • STRM:流式或非临时预取,数据使用后将淘汰,用于仅使用一次的数据。
    • Xn|SP:通常表示64位通用寄存器或栈指针,使用场景中通常为预取的起始地址。
    • pimm:以字节为单位的偏移量,取值为8的整数倍,范围是0到32760,默认为0。

从指令组成看,预取指令中核心部分为prfop,其决定了预取的类型、预取cache层级以及预取的数据使用模式。本小节主要说明PLD数据预取,其他模式类似,数据预取核心指令部分有以下几种使用方式。

数据预取指令

指令功能说明

PLDL1KEEP

数据预取到L1 cache,策略为keep模式,数据使用后常驻Cache。

PLDL2KEEP

数据预取到L2 cache,策略为keep模式,数据使用后常驻Cache。

PLDL3KEEP

数据预取到L3 cache,策略为keep模式,数据使用后常驻Cache。

PLDL1STRM

数据预取到L1 cache,策略为strm模式,数据使用后从Cache淘汰。

PLDL2STRM

数据预取到L2 cache,策略为strm模式,数据使用后从Cache淘汰。

PLDL3STRM

数据预取到L3 cache,策略为strm模式,数据使用后从Cache淘汰。

GCC编译器针对预取也有对应的builtin函数实现,格式如下:

__builtin_prefetch (const void *addr, int rw, int locality)

其中:

  • addr表示数据的内存地址。
  • rw为可选参数,rw可设置为0或1,0表示读操作,1表示写操作。
  • locality为可选参数,可设置0~3,表示数据在cache中保持的时间,即时效性。取值为0表示访问的数据后续不再被访问,使用后在cache中淘汰;取值为3表示访问的数据将再次访问;取值1和2则分别表示具有低时效性和中时效性,该值默认为3。

未使用软件预取:

int add_vector(int *dst, int *src1, int *src2, int size) 
{
for (int index =0 ; index < size; index += 4) {
…  // do something   
}
}

使用软件预取:

static inline void prefetch(const void* data)
 {
  __asm__ __volatile__(
    "prfm PLDL1STRM, [%[data]]         \n\t"
    :: [data] "r" (data));
}
int add_vector(int *dst, int *src1, int *src2, int size) 
{
  for (int index =0 ; index < size; index += 4) {
     prefetch(src1 + 256);
     prefetch(src2 + 256);
     … // do something 
  }
}
搜索结果
找到“0”个结果

当前产品无相关内容

未找到相关内容,请尝试其他搜索词