__builtin___clear_cache 是如何工作的?

2021-12-20 00:00:00 built-in caching c++

通过 gcc 文档,我偶然发现了内置函数 __builtin___clear_cache.

Going through the gcc documentation, I stumbled into the builtin function __builtin___clear_cache.

――内置函数:void __builtin____clear_cache (char *begin, char*end) 此函数用于刷新处理器的指令缓存,用于开始包含和结束不包含之间的内存区域.某些目标要求刷新指令缓存,之后修改包含代码的内存,以获得确定性行为.

― 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.

如果目标不需要指令缓存刷新,__builtin___clear_cache 没有效果.否则,要么内联发出指令以清除指令缓存,要么调用libgcc中的__clear_cache函数制作完成.

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 缓存(指令缓存)中.因此,乍一看,这个内置函数可能会严重破坏我们程序的流程,因为它会清除堆栈中的下一条指令.

I find this interesting, but surprising. In many cases, a large number of the instructions for the current stack is stored in the L1 cache (instruction cache). So it would seem at first glance that this builtin could corrupt significantly the flow of our program, by making it wipe out the next instructions on the stack.

这条指令是否也重新填充了 L1 缓存中的堆栈部分?

Does this instruction also repopulates the part of the stack that was in the L1 cache?

这似乎不太可能.如果没有,那么我想用户有责任使用正确的 beginend 参数,以免破坏我们的进程.在实践中,如何找到正确的 beginend 使用?

This seems unlikely. If it does not, then I suppose the onus is on the user to use the right begin and end arguments, so as to not corrupt our process. In practice, how could one find what the right begin and end to use?

推荐答案

它只是在需要它们的目标处理器上发出一些奇怪的机器指令 [s](x86 不需要).

It is just emitting some weird machine instruction[s] on target processors requiring them (x86 don't need that).

__builtin___clear_cache 视为刷新指令缓存的可移植"(对 GCC 和兼容编译器)方式(例如在某些 JIT 库).

Think of __builtin___clear_cache as a "portable" (to GCC and compatible compilers) way to flush the instruction cache (e.g. in some JIT library).

在实践中,如何找到正确的开始和结束使用?

In practice, how could one find what the right begin and end to use?

为了安全起见,我会在某些页面范围内使用它(例如,通过 sysconf(_SC_PAGESIZE).... 获得),所以通常是 4Kbyte 对齐的内存范围(4Kbyte 的倍数).否则,您需要一些特定于目标的技巧来找到缓存线宽...

To be safe, I would use that on some page range (e.g. obtained with sysconf(_SC_PAGESIZE)....), so usually a 4Kbyte aligned memory range (multiple of 4Kbyte). Otherwise, you want some target specific trick to find the cache line width...

在 Linux 上,您可以阅读 /proc/cpuinfo 并使用 cache_alignment &cache_size 行以获得更精确的缓存行大小和对齐方式.

On Linux, you might read /proc/cpuinfo and use the cache_alignment & cache_size lines to get a more precise cache line size and alignment.

顺便说一句,使用 __builtin__clear_cache 的代码很可能(出于其他原因)特定于目标机器,因此它具有或知道一些机器参数(并且应该包括缓存大小和对齐).

BTW, a code using __builtin__clear_cache is very likely to be (for other reasons) target machine specific, so it has or knows some machine parameters (and that should include cache size & alignment).

相关文章