2

我正在阅读英特尔架构文档,vol3,第 8.1.3 节

与非自修改或普通代码相比,自修改代码将以较低的性能水平执行。性能恶化的程度将取决于修改频率和代码的具体特性。

所以,如果我尊重规则:

(* OPTION 1 *) 将修改后的代码(作为数据)存储到代码段中;跳转到新代码或中间位置;执行新代码;

(* 选项 2 ) 将修改后的代码(作为数据)存储到代码段中;执行序列化指令;(例如CPUID指令*)执行新代码;

并且每周修改一次代码,我应该只在下次修改此代码并即将执行时支付罚款。但在那之后,性能应该与未​​修改的代码相同(+ 跳转到该代码的成本)。

我的理解正确吗?

4

2 回答 2

3

“下一次”可能不是这样;缓存算法考虑到第一个之外的访问(不这样做会很幼稚)。然而,在前几次访问之后不久,惩罚应该消失了。(“少数”可能是两个或数千个,但对于一台计算机来说,即使是一百万也不算什么。)

甚至当前正在执行的代码也在某个时候被写入内存(甚至可能是最近由于分页),所以它最初会经历类似的惩罚,但很快就会消失,所以你不必担心。

于 2015-12-01T09:56:34.747 回答
3

尚未缓存的代码与修改已经推测运行中的指令的代码之间存在差异(获取,可能已解码,甚至可能位于调度程序中并在乱序核心中重新排序缓冲区) . 写入已经被 CPU 视为指令的内存会导致它回退到非常慢的操作。这就是自修改代码通常的含义。即使 JIT 编译不太难,也可以避免这种减速。只是在全部写入之前不要跳到缓冲区。

每周修改一次意味着如果你做错了,你每周可能会受到一微秒的惩罚。确实,经常使用的数据不太可能从缓存中清除(这就是为什么多次读取某些内容更有可能使其“粘住”),但自修改代码管道刷新应该只应用第一个时间,如果你遇到它。之后,正在执行的缓存行处于概率状态。如果第二次运行没有太多干预代码,L1 I-cache(和 uop 缓存)中仍然很热。它在 L1 D-cache 中仍未处于修改状态。

我忘记了http://agner.org/optimize/是否谈论自修改代码和 JIT。即使没有,如果您在 ASM 中编写任何内容,您也应该阅读 Agner 的指南。不过,主要“优化 asm”中的一些内容已经过时,并且与 Sandybridge 和后来的 Intel CPU 并不真正相关。得益于 uop 缓存,对齐/解码问题不再是一个问题,而且对齐问题对于 SnB 系列微架构可能会有所不同。

于 2015-12-01T12:00:01.620 回答