当前位置: 首页 > 知识库问答 >
问题:

如何编写在现代x64处理器上高效运行的自修改代码?

方俊
2023-03-14

一般的技术被称为“子程序线程”(或“调用线程”,尽管这也有其他定义)。目标是利用处理器有效的调用/RET预测,以避免停顿。这里详细描述了该方法:http://webdocs.cs.ualberta.ca/~amaral/cascon/cdp05/slides/cdp05-berndl.pdf

生成的代码只是一系列的调用,后面跟着一个返回。如果有5个“块”的宽度[4,8,8,4,16],它看起来像:

call $decode_4
call $decode_8
call $decode_8
call $decode_4
call $decode_16
ret

在实际使用中,它将是一个更长的调用系列,具有足够的长度,每个系列可能是唯一的,只调用一次。代码的生成和调用在这里和其他地方都有很好的记录。但除了简单的“不要做”或深思熟虑的“有龙”之外,我还没有发现太多关于效率的讨论。即使是Intel的文档也大多是泛泛而谈:

对当前高速缓存在处理器中的代码段中的存储器位置的写入导致相关高速缓存行(或多行)无效。此检查基于指令的物理地址。此外,P6系列和奔腾处理器检查对代码段的写入是否可以修改已预取以供执行的指令。如果写影响预取指令,则预取队列无效。后一种检查基于指令的线性地址。对于Pentium4和Intel Xeon处理器,在目标指令已经解码并驻留在跟踪缓存中的代码段中写入或窥探指令将使整个跟踪缓存无效。后一种行为意味着自修改代码的程序在奔腾4和英特尔至强处理器上运行时会导致性能严重下降。

虽然有一个性能计数器来确定是否发生了坏事(C3 04 machine_clears.smc:检测到的自修改代码机器清除数),但我想知道更多细节,尤其是对于Haswell。我的印象是,只要我能在指令预取尚未到达的时间之前写出足够多的生成代码,只要我不通过修改同一页(四分之一页?)上的代码来触发SMC检测器作为目前正在执行的任何事情,那么我应该得到良好的性能。但所有的细节看起来都极其模糊:多近才算太近?多远才够远?

试图把这些变成具体的问题:

如何在预测的循环中运行生成/执行循环,同时防止预取器吃掉自己的尾巴?

我如何安排流,以便生成的每一段代码总是“第一次看到”,而不是踩到已经缓存的指令?

共有1个答案

谢弘阔
2023-03-14

这不是SMC的范围,而是动态二进制优化的范围,即--您并不真正操作正在运行的代码(就像编写新指令一样),您可以只生成一段不同的代码,并重新路由代码中适当的调用以跳转到那里。唯一的修改是在入口点,而且只做了一次,所以您不需要太担心开销(这通常意味着刷新所有管道,以确保旧指令在机器中的任何地方都不存在,我猜损失是数百个时钟周期,这取决于CPU负载的大小。只有在重复发生时才有意义)。

在同样的意义上,你不应该太担心提前足够的时间做这件事。顺便说一句,关于您的问题--CPU将只能在它的ROB大小之前开始执行,在haswell中是192 uop(不是指令,但足够接近),根据这个--http://www.realworldtech.com/haswell-cpu/3/,由于预测器和提取单元,CPU将能够看到更远的前面,所以我们谈论的是数百个单元)。

说到这里,让我重申一下之前在这里说过的话--实验,实验实验:)

 类似资料:
  • 关于代理,Java消息服务是如何工作的?我看到了创建producer的教程和示例

  • 本文向大家介绍如何编写高质量JS代码,包括了如何编写高质量JS代码的使用技巧和注意事项,需要的朋友参考一下 想写出高效的javascript类库却无从下手; 尝试阅读别人的类库,却理解得似懂给懂; 打算好好钻研js高级函数,但权威书上的内容太零散, 即使记住“用法”,但到要“用”的时候却没有想“法”。 也许你和我一样,好像有一顾无形的力量约束着我们的计划,让我们一再认为知识面的局限性,致使我们原地

  • 问题内容: 您是否曾经用Java 创建或遇到过自我修改的代码?如果是,请发布链接或直接发布代码。 问题答案: 忽略悲伤世界,您可能会通过自我修改代码(!)导致自己陷入困境,在我看来,这里有3种选择: 使用Java 6的内置编译器支持以及写入/重新编译/重新加载类 使用Apache BCEL字节码操作库直接编写您的类 利用Java 6的内置脚本支持(或使用Apache BSF)以您选择的JVM脚本语

  • 我在操作系统或编译器优化方面没有深厚的背景,也没有直接使用机器代码,但我开始探索它。我已经开始在assembly中玩了一圈,看看像NASM这样的东西如何将汇编代码编译成机器代码(可执行文件),然后您可以从命令行调用它,比如。 但是JIT编译器实际上是如何在运行时做到这一点的呢?它是像流机器代码到stdin或什么,或者它是如何工作的?如果您能提供一个示例或一些伪代码,说明一些程序集(或类似的东西,但

  • 本文向大家介绍如何编写高质量JS代码(续),包括了如何编写高质量JS代码(续)的使用技巧和注意事项,需要的朋友参考一下 继续上一篇文章《如何编写高质量JS代码》今次整理一下javascript函数知识点。 2.使用函数 函数给程序员提供了主要的抽象功能,又提供实现机制。函数可以独立实现其他语言中的多个不同的特性,例如,过程、方法、构造函数,甚至类或模块。 2.1 理解函数调用、方法调用以及构造函数

  • 问题内容: 我如何启用Notch 在Eclipse的此视频中谈论的“运行时调试”功能? 作为测试,我希望能够在运行时编辑以下代码的输出并将其更改为“ Hello Runtime Debugging”。 编辑: 我修改了代码,现在我得到了想要的结果。Suraj Chandran在下面的回答对此进行了解释。 问题答案: Eclipse开箱即用地支持调试期间的热交换代码。 在调试时,只需更改任何代码并保