In the book Linkers and Loaders, it's mentioned that one of the reasons for executables to have a separate code section is that the code section can be kept in read only pages, which results in a performance increase. Is this still true for a modern OS? Seeing as Just in Time compilers are generating code on the fly, I assume they need writable pages. Does this mean that JIT generated code will always suffer a performance hit in comparison? If so, how significant a hit is it?
在Linkers和Loaders一书中,提到可执行文件具有单独代码部分的原因之一是代码部分可以保存在只读页面中,这会导致性能提高。现代操作系统仍然如此吗?看到Just in Time编译器正在生成代码,我认为它们需要可写页面。这是否意味着JIT生成的代码总是会遭受性能损失?如果是这样,它有多重要?
3 个解决方案
#1
Effects of memory management aside (which are explained in other answers), CPU doesn't need to continuously check if the current stream of instructions are modified and the intermediate results in the pipeline should be thrown away and new code needs to be read. In the case of jit compilation, this scenario may occur often depending on the design of the compiler, depth of CPU pipeline, size of code cache on CPU and number of other CPUs which may modify that code. It isn't normally allowed to occur in well designed modern systems where code is generated to a writeable page and marked as executable and readonly afterwards. This is not unique to jit of course. It can happen in all kinds of self modifying code.
除了内存管理的影响(在其他答案中解释),CPU不需要连续检查当前的指令流是否被修改,并且应该丢弃管道中的中间结果并且需要读取新代码。在jit编译的情况下,这种情况可能经常发生,这取决于编译器的设计,CPU管道的深度,CPU上的代码高速缓存的大小以及可能修改该代码的其他CPU的数量。通常不允许在设计良好的现代系统中进行,其中代码生成到可写页面并且之后标记为可执行和只读。这当然不是jit独有的。它可以发生在各种自修改代码中。
#2
Yes, it should suffer some sort of hit because the code in memory is not backed directly by the executable, so it would have to be paged out instead of just dropped. Having said that, various forms of linking can also dirty up regular code pages so that they no longer match the disk image, with the same consequences, so I'm not sure that this is a big deal.
是的,它应该遭受某种打击,因为内存中的代码不是由可执行文件直接支持的,所以它必须被分页而不是丢弃。话虽如此,各种形式的链接也会弄乱常规代码页,使它们不再与磁盘映像匹配,产生相同的后果,所以我不确定这是一个大问题。
#3
The performance increase is not because of whether the pages are read only or not. The advantage is that read only pages can be shared between processes, so you use less memory which means less swapping (both to L1/L2/L3 caches as well as to disk in extreme cases).
性能提升不是因为页面是否是只读的。优点是可以在进程之间共享只读页面,因此您可以使用更少的内存,这意味着更少的交换(在极端情况下,无论是L1 / L2 / L3缓存还是磁盘)。
JIT tries to mitigate this by not needlessly JITting, but only JITting the hot functions. This will result in only a modest increase in memory since the number of hot functions are relatively small.
JIT试图通过不必要的JITting缓解这个问题,但只是JITting热门函数。由于热功能的数量相对较少,这将导致存储器仅适度增加。
A JIT compiler could also be smart and cache the result of the JITting so it could (theoretically) be shared. But I don't know whether this is done in practice.
JIT编译器也可以是智能的并缓存JITting的结果,因此它(理论上)可以共享。但我不知道这是否在实践中完成。
#1
Effects of memory management aside (which are explained in other answers), CPU doesn't need to continuously check if the current stream of instructions are modified and the intermediate results in the pipeline should be thrown away and new code needs to be read. In the case of jit compilation, this scenario may occur often depending on the design of the compiler, depth of CPU pipeline, size of code cache on CPU and number of other CPUs which may modify that code. It isn't normally allowed to occur in well designed modern systems where code is generated to a writeable page and marked as executable and readonly afterwards. This is not unique to jit of course. It can happen in all kinds of self modifying code.
除了内存管理的影响(在其他答案中解释),CPU不需要连续检查当前的指令流是否被修改,并且应该丢弃管道中的中间结果并且需要读取新代码。在jit编译的情况下,这种情况可能经常发生,这取决于编译器的设计,CPU管道的深度,CPU上的代码高速缓存的大小以及可能修改该代码的其他CPU的数量。通常不允许在设计良好的现代系统中进行,其中代码生成到可写页面并且之后标记为可执行和只读。这当然不是jit独有的。它可以发生在各种自修改代码中。
#2
Yes, it should suffer some sort of hit because the code in memory is not backed directly by the executable, so it would have to be paged out instead of just dropped. Having said that, various forms of linking can also dirty up regular code pages so that they no longer match the disk image, with the same consequences, so I'm not sure that this is a big deal.
是的,它应该遭受某种打击,因为内存中的代码不是由可执行文件直接支持的,所以它必须被分页而不是丢弃。话虽如此,各种形式的链接也会弄乱常规代码页,使它们不再与磁盘映像匹配,产生相同的后果,所以我不确定这是一个大问题。
#3
The performance increase is not because of whether the pages are read only or not. The advantage is that read only pages can be shared between processes, so you use less memory which means less swapping (both to L1/L2/L3 caches as well as to disk in extreme cases).
性能提升不是因为页面是否是只读的。优点是可以在进程之间共享只读页面,因此您可以使用更少的内存,这意味着更少的交换(在极端情况下,无论是L1 / L2 / L3缓存还是磁盘)。
JIT tries to mitigate this by not needlessly JITting, but only JITting the hot functions. This will result in only a modest increase in memory since the number of hot functions are relatively small.
JIT试图通过不必要的JITting缓解这个问题,但只是JITting热门函数。由于热功能的数量相对较少,这将导致存储器仅适度增加。
A JIT compiler could also be smart and cache the result of the JITting so it could (theoretically) be shared. But I don't know whether this is done in practice.
JIT编译器也可以是智能的并缓存JITting的结果,因此它(理论上)可以共享。但我不知道这是否在实践中完成。