通过gcc文档,我偶然发现了内置函数__builtin___clear_cache
。
- 内置函数:void __builtin___clear_cache(char * begin,char * end)此函数用于在开始包含和结束排除之间刷新处理器的内存区域的指令高速缓存。 有些目标要求在之后刷新指令高速缓存 修改包含代码的内存,以获得确定性 行为。
如果目标不需要指令缓存刷新, __builtin___clear_cache无效。否则,将在线发出任一指令以清除指令高速缓存或调用指令 在libgcc中创建__clear_cache函数。
我发现这很有趣,但令人惊讶。在许多情况下,当前堆栈的大量指令存储在L1高速缓存(指令高速缓存)中。因此,乍一看,这个内置程序可能会显着破坏我们程序的流程,使其消除堆栈中的下一条指令。
此指令是否还重新填充L1缓存中的堆栈部分?
这似乎不太可能。如果没有,那么我认为用户有责任使用正确的begin
和end
参数,以免破坏我们的进程。在实践中,如何才能找到正确使用begin
和end
的内容?
答案 0 :(得分:2)
它只是在需要它们的目标处理器上发出一些奇怪的机器指令(x86不需要它)。
将__builtin___clear_cache
视为“可移植”(以GCC和兼容的编译器)方式来刷新指令缓存(例如,在某些JIT库中)。
在实践中,如何才能找到正确的开始和结束用途?
为了安全起见,我会在某些页面范围内使用它(例如,使用sysconf(_SC_PAGESIZE)
....获得),因此通常是4K字节对齐的内存范围(4Kbyte的倍数)。否则,您需要一些特定于目标的技巧来查找缓存行宽...
在Linux上,您可以阅读/proc/cpuinfo
并使用cache_alignment
& cache_size
行可以获得更精确的缓存行大小和对齐方式。
__builtin__clear_cache
的代码很可能(由于其他原因)特定于目标机器,因此它具有或知道某些机器参数(并且应包括缓存大小和对齐)。