【发布时间】:2018-10-30 02:10:35
【问题描述】:
如何在用户空间代码中刷新 aarch64 上的缓存行?就像在 x86 上一样,我们可以使用以下 lib 调用:
_mm_clflush(&array);
我尝试了以下代码:
void flush(void)
{
asm volatile ( "MCR p15, 0, =0x0,c7, c6, 0\n");
return;
}
但是GCC有编译错误:
Error: unknown mnemonic `mcr' -- `mcr p15,0,=0x0,c7,c6,0'
谢谢。
@Peter 的评论更新:
我用以下代码尝试了__builtin___clear_cache:
int tt = 0;
unsigned long *ptr;
tt++;
TIMESTAMP(ts2);
printf("cycle: %lu. %d\n", ts2-ts1, tt);
ptr = &tt;
__builtin___clear_cache(ptr, ptr+128);
TIMESTAMP(ts1);
tt++;
TIMESTAMP(ts2);
printf("cycle: %lu. %d\n", ts2-ts1, tt);
结果似乎没有显示我们已成功将数据从数据缓存中逐出:
cycle: 5. 1
cycle: 0. 2
我查看了反汇编,并引用了the AARCH64 instruction manual。好像内置函数清理了缓存吧?
0000000000400788 <__clear_cache>:
400788: 14000002 b 400790 <__aarch64_sync_cache_range>
40078c: 00000000 .inst 0x00000000 ; undefined
0000000000400790 <__aarch64_sync_cache_range>:
400790: b0000083 adrp x3, 411000 <_GLOBAL_OFFSET_TABLE_+0x28>
400794: b9404462 ldr w2, [x3,#68]
400798: 35000082 cbnz w2, 4007a8 <__aarch64_sync_cache_range+0x18>
40079c: d53b0024 mrs x4, ctr_el0
4007a0: 2a0403e2 mov w2, w4
4007a4: b9004464 str w4, [x3,#68]
4007a8: d3504c44 ubfx x4, x2, #16, #4
4007ac: 52800083 mov w3, #0x4 // #4
4007b0: 12000c45 and w5, w2, #0xf
4007b4: 1ac42064 lsl w4, w3, w4
4007b8: 51000482 sub w2, w4, #0x1
4007bc: 1ac52063 lsl w3, w3, w5
4007c0: 8a220002 bic x2, x0, x2
4007c4: 93407c84 sxtw x4, w4
4007c8: eb01005f cmp x2, x1
4007cc: 540000a2 b.cs 4007e0 <__aarch64_sync_cache_range+0x50>
4007d0: d50b7b22 dc cvau, x2
4007d4: 8b040042 add x2, x2, x4
4007d8: eb02003f cmp x1, x2
4007dc: 54ffffa8 b.hi 4007d0 <__aarch64_sync_cache_range+0x40>
4007e0: d5033b9f dsb ish
4007e4: 51000462 sub w2, w3, #0x1
4007e8: 93407c63 sxtw x3, w3
4007ec: 8a220000 bic x0, x0, x2
4007f0: eb00003f cmp x1, x0
4007f4: 540000a9 b.ls 400808 <__aarch64_sync_cache_range+0x78>
4007f8: d50b7520 ic ivau, x0
4007fc: 8b030000 add x0, x0, x3
400800: eb00003f cmp x1, x0
400804: 54ffffa8 b.hi 4007f8 <__aarch64_sync_cache_range+0x68>
400808: d5033b9f dsb ish
40080c: d5033fdf isb
400810: d65f03c0 ret
400814: 00000000 .inst 0x00000000 ; undefined
【问题讨论】:
-
您要同步数据/指令缓存吗? GNU C 的
__builtin__clear_cache会这样做:How does __builtin___clear_cache work? 或者你真的需要从缓存中驱逐数据的东西吗?__builtin__clear_cache将不一定这样做,尽管名称。 -
我应该包含什么头文件才能使用
__buildin__clear_cache?我想从 aarm64 上的缓存中清除数据。谢谢。 -
参见ARMv8 Reference Manual,从 C5-409 页开始。注意EL0访问可以关闭,见this answer of mine。
-
没有头文件。这就是内置函数的全部意义所在。它是预定义的。 gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html。另请注意,您有一个错字,它是
builtin而不是buildin。检查你得到什么asm;就像我说的那样,它实际上可能不会从数据缓存中逐出数据,如果它可以在不这样做的情况下将其同步到指令缓存。 -
谢谢@PeterCordes。我用你提到的内置更新。使用手册好像清除了缓存,但是结果并没有显示清除缓存的效果。
标签: caching cpu-architecture arm64