【问题标题】:May a compiler ever generate code to unload parts of the code segment during execution?编译器是否可以在执行期间生成代码来卸载部分代码段?
【发布时间】:2011-04-17 09:58:15
【问题描述】:

除了提供在运行时加载/卸载方法或函数的能力的 Dll 概念之外,我想知道编译器是否会说类似这样的话,因为代码的这个特定部分在代码中占用了大量空间段并且在程序执行期间的这一点之后永远不会再次使用,最好生成一些代码以在程序执行期间到达该特定点后卸载该部分代码段,以便代码段占用的整体空间变得更小。这只是虚构的事情还是可能会发生?

【问题讨论】:

    标签: c++ compiler-construction segment


    【解决方案1】:

    当然。有一种称为overlaying 的技术可以在不同的时间将不同的代码加载到地址空间的同一位中。有时它是手动完成的,有时编译器会提供帮助。有时加载是在软件中完成的,有时是在硬件中完成的(使用地址多路复用,例如,在启动期间,一位地址空间从 ROM 芯片读取,但在启动后它切换到地址 RAM 或不同的 ROM)。

    当计算机内存较少时,覆盖更为常见,例如在 DOS 的早期,您最多只有 640K,而且通常甚至没有。如今,它仍然适用于内存和/或地址空间非常宝贵的嵌入式系统。

    【讨论】:

      【解决方案2】:

      编译器可以做它想做的任何事情,只要不违反标准。如果它可以确定代码不再被调用,它可以完全放弃它。

      如果需要,它甚至可以用一个更小的存根函数替换它,该函数会重新加载代码。

      但您不太可能在现代操作系统中看到这一点,因为操作系统本身在幕后提供了该功能。

      操作系统(至少是常见的)会在内存不足时换出您的物理页面,并且在需要它们之前不会重新加载它们(通常是在尝试访问它们时出现页面错误)。

      【讨论】:

        【解决方案3】:

        是的,Windows 设备驱动程序使用这种技术。 LE file 格式将某些代码段标记为可丢弃。操作系统也可以在某些时候做出这样的决定,以换出长时间未使用的代码段。

        然而,严格来说,这不是编译器可以玩弄的地方。影响这一点的主要是链接器/加载器/操作系统。

        【讨论】:

        • 可丢弃的代码段也存在于 EXE 和 DLL 使用的更常见的 PE 格式中。编译器当然在这里发挥作用。它将功能放置在特定的部分中。但是,正如您所指出的,它没有什么意义:操作系统可以丢弃所有可重新加载的只读页面,并且会丢弃最近未触及的页面。
        【解决方案4】:

        我不知道有哪个编译器可以做到这一点,但没有禁止它的规则。如果编译器能证明这样做不会改变程序的语义,那么在as-if规则下是允许的。

        但通常没有必要,因为未使用的代码已经作为与虚拟内存相关的页面文件机制的一部分被换出。 (而且因为您可能只会节省几 KB 的内存空间)

        【讨论】:

          猜你喜欢
          • 2010-10-24
          • 1970-01-01
          • 2021-02-17
          • 2012-05-12
          • 1970-01-01
          • 2013-01-05
          相关资源
          最近更新 更多