__builtin___clear_cache 是如何运作的?
How does __builtin___clear_cache work?
通过 gcc 文档,我偶然发现了内置函数 __builtin___clear_cache
。
— Built-in Function: void __builtin___clear_cache (char *begin, char
*end) This function is used to flush the processor's instruction cache for the region of memory between begin inclusive and end exclusive.
Some targets require that the instruction cache be flushed, after
modifying memory containing code, in order to obtain deterministic
behavior.
If the target does not require instruction cache flushes,
__builtin___clear_cache has no effect. Otherwise either instructions are emitted in-line to clear the instruction cache or a call to the
__clear_cache function in libgcc is made.
我觉得这很有趣,但令人惊讶。在很多情况下,当前堆栈的大量指令都存储在L1缓存(instruction cache)中。所以乍一看,这个内置函数似乎会严重破坏我们程序的流程,因为它会清除堆栈中的下一条指令。
这条指令是否也重新填充了 L1 缓存中的堆栈部分?
这似乎不太可能。如果没有,那么我想用户有责任使用正确的 begin
和 end
参数,以免破坏我们的流程。在实践中,如何找到正确的 begin
和 end
来使用?
它只是在需要它们的目标处理器上发出一些奇怪的机器指令[s](x86 不需要)。
将 __builtin___clear_cache
视为一种 "portable"(对于 GCC 和兼容编译器)刷新指令缓存的方式(例如在某些 JIT 库中)。
In practice, how could one find what the right begin and end to use?
为了安全起见,我会在某些页面范围内使用它(例如通过 sysconf(_SC_PAGESIZE)
... 获得),因此通常是 4Kbyte 对齐的内存范围(4Kbyte 的倍数)。否则,您需要一些特定于目标的技巧来查找缓存行宽度...
在 Linux 上,您可以阅读 /proc/cpuinfo
并使用 cache_alignment
和 cache_size
行来获得更精确的缓存行大小和对齐方式。
顺便说一句,使用 __builtin__clear_cache
的代码很可能(出于其他原因)是特定于目标机器的,因此它具有或知道一些机器参数(并且应该包括缓存大小和对齐方式)。
通过 gcc 文档,我偶然发现了内置函数 __builtin___clear_cache
。
— Built-in Function: void __builtin___clear_cache (char *begin, char *end) This function is used to flush the processor's instruction cache for the region of memory between begin inclusive and end exclusive. Some targets require that the instruction cache be flushed, after modifying memory containing code, in order to obtain deterministic behavior.
If the target does not require instruction cache flushes, __builtin___clear_cache has no effect. Otherwise either instructions are emitted in-line to clear the instruction cache or a call to the __clear_cache function in libgcc is made.
我觉得这很有趣,但令人惊讶。在很多情况下,当前堆栈的大量指令都存储在L1缓存(instruction cache)中。所以乍一看,这个内置函数似乎会严重破坏我们程序的流程,因为它会清除堆栈中的下一条指令。
这条指令是否也重新填充了 L1 缓存中的堆栈部分?
这似乎不太可能。如果没有,那么我想用户有责任使用正确的 begin
和 end
参数,以免破坏我们的流程。在实践中,如何找到正确的 begin
和 end
来使用?
它只是在需要它们的目标处理器上发出一些奇怪的机器指令[s](x86 不需要)。
将 __builtin___clear_cache
视为一种 "portable"(对于 GCC 和兼容编译器)刷新指令缓存的方式(例如在某些 JIT 库中)。
In practice, how could one find what the right begin and end to use?
为了安全起见,我会在某些页面范围内使用它(例如通过 sysconf(_SC_PAGESIZE)
... 获得),因此通常是 4Kbyte 对齐的内存范围(4Kbyte 的倍数)。否则,您需要一些特定于目标的技巧来查找缓存行宽度...
在 Linux 上,您可以阅读 /proc/cpuinfo
并使用 cache_alignment
和 cache_size
行来获得更精确的缓存行大小和对齐方式。
顺便说一句,使用 __builtin__clear_cache
的代码很可能(出于其他原因)是特定于目标机器的,因此它具有或知道一些机器参数(并且应该包括缓存大小和对齐方式)。