我正在阅读英特尔架构文档,vol3,第8.1.3节;
自修改代码将以比非自修改代码或普通代码更低的性能执行.性能下降的程度将取决于修改的频率和代码的具体特性。
所以,如果我尊重这些规则:
(*选项1 *)将修改后的代码(作为数据)存储到代码段;跳转到新代码或中间位置;执行新代码; (*选项2)将修改后的代码(作为数据)存储到代码段中;执行序列化指令;(例如,CPUID指令*)执行新代码;
并且每周修改一次代码,,我只应该在下一次修改该代码并即将执行时支付相应的代价。但在此之后,性能应该与未修改的代码相同(+跳到该代码的成本)。
我的理解正确吗?
发布于 2015-12-01 12:00:01
还没有缓存的代码和已经在运行中进行推测的修改指令的代码之间有一个区别(获取,可能解码,甚至位于调度器中,或者在无序内核中重新排序缓冲区)。写入已被CPU视为指令的内存,使其返回到非常慢的操作中。这就是通常所说的自修改代码的含义。即使在JIT编译不太困难的时候,也要避免这种减速。只是不要跳转到你的缓冲区,直到它写好了。
每周修改一次意味着如果你做错了,你可能每周有一次微秒的惩罚。确实,频繁使用的数据不太可能被从缓存中逐出(这就是为什么多次读取某些内容更有可能使其“粘住”),但自修改代码管道刷新应该只在第一次应用,如果您完全遇到它。在此之后,正在执行的缓存行在prob中。在L1 i-缓存(和uop缓存)中仍然很热,如果第二次运行没有太多的干预代码。在L1 D-缓存中,它还没有处于修改状态.
我忘了http://agner.org/optimize/是否谈到了自修改代码和JIT。即使没有,如果你正在用ASM写任何东西,你也应该阅读Agner的指南。不过,主要的“优化asm”中的一些东西已经过时了,与沙桥和后来的英特尔CPU没有什么关系。由于uop缓存,对齐/解码问题不那么重要,对于SnB家族微弧来说,对齐问题可能有所不同。
发布于 2015-12-01 09:56:34
“下一次”可能不是这样;缓存算法考虑的是第一次访问之外的访问(不这样做将相当幼稚)。然而,在开始几次访问后不久,惩罚就应该消失了。(“很少”可能是两千,但对一台电脑来说,一百万也不算什么。)
即使是当前正在执行的代码也会在某个时候(甚至最近由于分页)被写入内存,因此最初也会遇到类似的损失,但很快就会消失,因此您不必担心。
https://stackoverflow.com/questions/34017361
复制相似问题