按以下流程测L2cache,发现一个现象,请教一下大家。
芯片是xilinx的zynq,L2 size = 512K。
程序本身加载到0x100000。
关闭所有中断。
使能L1和L2。
把0xfc000000开始的512K数据lock到L2中。
反复读写0x140000开始的64K内存。这样,L2虽使能,但却恒定miss,程序能跑890遍/秒。
跑一段时间后,执行DisableL2Cache。程序能跑865遍/秒。
为什么,L2 enable时,即使恒定miss,也比L2 disable 快一些?
感觉你是想对比测试memcpy在L2 cache disabled和L2里面所有cache memory被lock情况下的带宽吗?
为了回答你的问题,有几个问题需了解一下:
1) “恒定miss” 具体指的是什么? L2 cache miss? 如何测试得到的数据?
2) 看了一下xilinx网站,zynq 用的Cortex-A9。没有谈到L2的具体情况,用的是PL310吗(可以做instruction和data的prefetch)? 具体是哪一款zynq,看他们网站有Single-core和Dual-core。
3) 0x140000开始的64K内存 在MMU里面的配置属性是什么?
4) L2 cache lock的代码能否贴出来。
5) 你的测试是在baremetal,还是有OS的情况下的测试。
多谢。
1、恒定miss是指,我把0xfc000000开始的512K 内存lock到L2,然后访问0x140000开始的内存。由于lock后,cache不会再替换,故可确认恒定miss。
2、确实是PL310,zynq7015
3、mmu属性是00107dee,即outer = inner=“writeback,enable cache,no write allocation”
4、baremetal。
代码如下:
volatile u32 temp,*p_start;
for(i=0;i<8;i++)
{
Xil_Out32((XPS_L2CC_BASEADDR + (XPS_L2CC_CACHE_DLCKDWN_0_WAY_OFFSET + (i*8)) ), 0);
Xil_Out32((XPS_L2CC_BASEADDR + (XPS_L2CC_CACHE_ILCKDWN_0_WAY_OFFSET + (i*8)) ), 0);
}
Xil_DCacheFlush();
Xil_DCacheInvalidate();
//lock to L2 cache
for(p_start = (u32*)0xfc000000; p_start < (u32*)(0xfc000000+0x80000); p_start++)
temp = *p_start;
Xil_Out32((XPS_L2CC_BASEADDR + (XPS_L2CC_CACHE_DLCKDWN_0_WAY_OFFSET + (i*8)) ), 0xffff);
Xil_Out32((XPS_L2CC_BASEADDR + (XPS_L2CC_CACHE_ILCKDWN_0_WAY_OFFSET + (i*8)) ), 0xffff);
你的想法是用0xfc000000开始的数据填充整个L2 cache, 但是你没法完全做到,比如instruction 可能有部分在里面,也许还有部分其它Data。可能对都后面的memcpy带来好处。
可以看一下这两种情况下cache miss有什么不同。
另外PL310支持prefetch。 即使所有的cache被lock, 这个行为依然有效。假如刚好L1 memory sysyem来了数据请求,预取的数据会直接传到L1, 这样有可能对性能有提升。
不好意西,我没说清楚。
该段代码运行在 0~1M,该空间在mmutable中完全禁止cache了,因此L2cache的填充,肯定是有效的。
您的意思是,即使miss,PL310还是会执行prefetch,因此提高了些许速度?
有这个可能性, 具体CPU的行为需要仿真一下才知道。但这样查的话比较耗时间。要是你有ARM 的support服务的话,可以发邮件到support@arm.com
请问在os的情况下如何把数据lock在L2 cache的特定区域呢?相关的指令是什么呢?可以去哪查找资料呢?望您指教!