我有一系列在集群上运行的可执行文件,它们在执行开始时读取一些小的配置文件,然后进行几个小时的大量处理,然后写出一些数据并退出。我们的系统管理员试图告诉我我们的文件服务器真的很慢,因为他的分析表明集群节点在 ELF 可执行文件生成后很久都在使用 NFS 磁盘 I/O 读取来执行(注意:我们的可执行文件只有几 MB 大小)。这对我来说听起来不对,因为我的印象是动态链接器在运行时将整个可执行文件加载到内存中,然后在内存不足的情况下运行。我知道内核在运行时会为可执行文件留下一个打开的文件描述符,但我不认为它会不断地从中读取。
我的问题是,我对可执行文件加载方式的理解是否存在缺陷?我发现很难相信内核会不断地对可执行文件进行文件读取以获取指令,因为这会非常慢(即使使用缓存),因为分支预测几乎不可靠,因此您将永远花费从读取可执行文件如果您的二进制文件执行频繁跳转,则磁盘。
最佳答案
I was under the impression that the dynamic linker loaded the entire executable into memory at runtime and then operated out of memory.
您的印象不正确。
首先,一个小错误:虽然动态链接器负责加载共享库,但主要可执行文件本身在动态加载器启动之前由内核加载。
其次,大多数当前系统使用demand paging .这些文件是 mmap
ed,但在访问该代码(即尝试执行)之前,代码实际上并未加载到内存中。如果您从未执行过程序的某些部分,那么这些部分永远不会根本不会加载到内存中。
I find it hard to believe that the kernel is constantly doing file reads on the executable to fetch instructions
它不会经常那样做。它通常将代码加载到内存中,并且代码保留在那里。
在没有足够内存的系统上,代码可能会从内存中被丢弃(如果再次执行则需要重新加载)(这称为抖动)。
because branch predictions are hardly reliable,
分支预测
- 与您的问题几乎无关,并且
- 在现代 CPU 上非常好。
关于ELF 执行期间的 Linux 内存/磁盘行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43209964/