我尝试测量我的L1(指令)缓存延迟。(32KB,8路,64B大小线)
为此我写了一个内核模块:
这个想法是:
1. I disable interrupts(cli)
2. I work with only one cpu with only one core : i do that with 'maxcpus=1' in grub.
3. I fill the L1 instruction cache and I measure latency with rdtsc:
3a : rdtsc
3b : fill set 0
3c : rdtsc and compute the difference between this step and the step 3a
3d : repeat for all set!
4. I enable interrupts(sti)
我做了大约1000项措施。 900号给我:
set 0 : 228
set 1 : 54
set 2 : 42
set 3 : 150
set 4 : 42
set 5 : 150
set 6 : 42
set 7 : 144
set 8 : 42
set 9 : 144
set 10 : 42
set 11 : 144
set 12 : 42
set 13 : 144
set 14 : 36
set 15 : 144
set 16 : 42
set 17 : 150
set 18 : 42
set 17 : 150
set 18 : 42
set 19 : 150
set 20 : 42
set 21 : 144
set 22 : 42
set 23 : 150
set 24 : 42
set 25 : 156
set 26 : 42
(...)
所以我猜我的L1缓存延迟是42 ......
但正如你所看到的那样,似乎有两次缓存错过。
所以我的问题是这些缓存未命中的来源是什么? (为了记住我禁用了中断)
我预计在第二次测量后几乎不变的时间,但似乎我错了。
另外,我想测量L2缓存延迟。你认为我可以采用相同的方法吗?
谢谢
编辑:
我在http://www.iacr.org/archive/ches2010/62250105/62250105.pdf找到了用于填充和测量缓存的代码。
您会在http://pastebin.com/SeZBwgnK
找到C / asm代码您可以在http://pastebin.com/dCtntswM
找到Makefile编辑2: 我修改了上一个代码:你可以在(1)http://pastebin.com/X5LZUtVL
找到它我只是想测量L1缓存中最后一组的延迟(设置数字63)。 为了防止分支预测,我随机跳过RAM" line"这些都在63集中: 而不是一步一步地跳64,我随机做(我不关心其他人): jmp L63 - > jmp L447 ---> jmp L255 ---> jmp L127 ---> jmp L383 ---> jmp L319 ---> jmp L191 - > jmp L511
代替: jmp L63 - > jmp L127 ---> jmp L191 ---> jmp L255 ---> jmp L319 ---> jmp L383 ---> jmp L447 - > jmp L511
但这样做会导致每个jmp的错误预测吗?
关于乱序,我现在在rdtsc之前使用mfence。 我也测量了" mfence; rdtsc"使用程序(仍然是禁用中断的内核模块)。你可以在(2)http://pastebin.com/EQVPA3iA找到它,这可以证明这些指示有多长。 我做了很多次测量,(2)的输出给了我"(...)56,60,60,60,60,60,60,56,60(...)" 。 它有四个不同的差异来自哪里?平均而言,这些指令需要58个周期。
现在我启动内核模块(1),它给了我:"(...)102,108,102,108,102,(...)" 有6个周期的差异(而不是超过144-42 = 102我的程序的第一个版本,但两次仍有差异)它来自哪里?在averge L1缓存访问中使用" mfence; rdtsc"给我105个周期。 所以没有" mfence; rdtsc" L1缓存访问是105-58 = 47 也许是因为误预测?