在 x86 架构上,“扩展分页”允许页框(物理内存)为 4 MB 而不是 4 KB。
“Understanding the Linux Kernel, 3rd”一书第2章“Memory Addressing”,子章“Paging in Linux”,“Kernel Page Tables”部分,解释了当RAM大小小于896 MB时的最终内核页表:
[...] 内核可以通过使用大页来寻址 RAM(参见本章前面的“扩展分页”部分)。
但是,在“扩展分页”部分(“硬件分页”子章节)中,它是这样写的:
扩展分页与常规分页共存。
我实际上不知道扩展和常规分页是如何共存的。请有人解释这些问题:
如果进程想要访问不在物理内存中的内存地址,操作系统会将页面框架从物理内存外包给硬盘驱动器以备后用。此数据/指令存储在硬盘驱动器上的哪个位置?
它存储在交换分区上吗?
我想将内核的页面大小从 4KB 更改为 4MB,因为我的计算机增加了大量 RAM,而且我再也不会用完。
这个想法是需要大量内存的程序将在分配页面上花费更少的时间。我想它会提高性能,我想尝试一下。
运行时找不到任何地方make menuconfig。有没有办法做到这一点?
我正在使用在Linux下运行的集群机器。
我有一个 shell 脚本,用于mpirun将我的作业提交到集群计算机。在同一脚本中,我可以选择分配给作业的节点数量。到目前为止,一切都很好。
我的问题出现在:当我提交一些作业时,一切正常,但是,当我填满节点的容量时,某些提交的作业将无法完成。因此,我怀疑集群上的可用内存不足以同时处理我的所有作业。
这就是为什么我想检查每个作业随着时间的推移的内存使用情况,然后我使用该qstat -f命令,但它显示了很多东西,其中大多数我无法理解。
所以这是我的问题:在下面命令的示例输出中qstat -f,我们可以看到两种类型的内存:mem和vmem。我想知道这两者有什么区别,实际使用的内存量是多少?
resources_used.cput = 00:21:04
resources_used.mem = 2099860kb
resources_used.vmem = 40505676kb
resources_used.walltime = 00:21:08
Run Code Online (Sandbox Code Playgroud)
此外,如果有详细说明该命令输出的参考资料,我将不胜感激。我尝试了 man qstat 但它没有详细说明每个返回行。
我有一个 Terasic-SoCKIT(fpga 和 arm cortex a9),我在 HPS 上运行 Linux。我正在尝试访问内存映射 I/O,编写了一个带有函数“request_mem_region”和“ioremap”的简单字符驱动程序。
内存映射 IO 是 AXI 总线,我可以使用它向 FPGA 传输数据。我看到每次写入大约需要 6us,对于我的应用程序,我需要它小于 1us。此外,驱动程序在几次写入后停止写入映射的 IO(看不到 fpga 中的数据正在更改;驱动程序中的缓冲区是否已满??)。
问题是我是否遗漏了什么,或者因为写入是从虚拟地址到物理地址发生的,所以它不能再快了?如果从虚拟地址写入速度变慢,有没有办法加快速度?我知道,ARM 有一个 DMAC,但我还没有探索它。
谢谢你,卡西克
对不起,我没说我正在测量用户空间代码中的时间。后来查了一下驱动写入的时间,是纳秒级。所以,我认为大部分时间是从用户空间写入内核。
所以,我做了一些进一步的阅读并了解到 ioremap() 将物理地址映射到内核虚拟地址,而 remap_pfn_range() 将物理地址/IO 内存映射到用户虚拟空间(这就是我需要的;从用户写入 IO 内存空间)。我使用了简单的 mmap 示例 - http://web.cecs.pdx.edu/~jrb/ui/linux/examples.dir/simple/simple.c作为内核驱动程序。以下代码是我的用户空间代码:
using namespace std;
#include <iostream>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <ctime>
#define PAGE_SIZE 4096
#define HPS2FPGA_BRIDGE_BASE 0xc0000000
#define BLINK_OFFSET 0x0
volatile unsigned char *blink_mem;
void *bridge_map; …Run Code Online (Sandbox Code Playgroud) 有没有办法只将交换空间或交换文件分配给一个进程或一组进程,而其他进程仍然使用正常的交换机制?
这是一些上下文。我有一个使用大量内存(大于物理内存)的进程,我想将仅由该进程拥有的交换页面定向到我在 SSD 上创建的交换文件。
我正在使用 Linux。如果这有助于解决方案,我愿意使用容器。
假设我想用交换(实际上是一个 zram)终止 Linux 机器上的一个进程。交换是 RAM 大小的一半。RAM 中只有 10% 的可用空间,交换区也几乎满了。
该进程仅使用了 2% 的 RAM,但使用了大约 90% 的交换空间。
执行软关闭 (SIGTERM) 并允许进程捕获信号并自行关闭将导致取消交换所有交换的映射,但没有足够的可用 RAM 来适应整个进程。
因此,使用 SIGKILL 终止进程可能会更好,但我仍然担心 OOM-killer 会因内存不足而终止其他进程甚至整个 X 会话或 init。
那么发送一个终止信号会让内核将进程的交换部分移动到物理内存中吗?(我应该期待什么?它取决于内核的版本吗?)
如果是这样,在这种情况下该怎么办?目标是在不触及其余进程的情况下终止进程(还有其他重要进程正在运行)。
此外,当它不是一个进程而是一个进程的树并且我不能让应用程序自行终止时,如何正确杀死它?
根据我的理解,每个进程通过虚拟地址而不是物理地址访问内存,通过MMU单元将这些虚拟地址转换为物理地址是CPU的职责,两个或多个进程可以有相同的虚拟地址。
因此,假设进程 A正在尝试访问虚拟地址12345,而进程 B正在尝试访问虚拟地址12345。
MMU将如何将每个进程的虚拟地址转换为物理地址,是否有每个进程的映射表将虚拟地址映射到物理地址(因为我以为CPU甚至不知道“进程”是什么,它唯一的职责是盲目执行指令而不关心哪个指令属于哪个进程,而“进程”只是一个操作系统概念)?
在 Linux 机器上,我们可以通过如下命令启用交换
sudo fallocate -l 500M /data/swapfile
sudo chmod 600 /data/swapfile
sudo mkswap /data/swapfile
sudo swapon /data/swapfile
Run Code Online (Sandbox Code Playgroud)
但即使未启用此功能,当页面不在内存中时,内核仍会进行分页。
我们可以通过sar -B 1 30在机器上运行命令来验证这一点,而无需设置任何交换文件。
03:08:40 AM pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff
03:08:41 AM 0.00 0.00 3.00 0.00 44.00 0.00 0.00 0.00 0.00
03:08:42 AM 0.00 0.00 19.00 0.00 30.00 0.00 0.00 0.00 0.00
03:08:43 AM 0.00 0.00 0.00 0.00 3.00 0.00 0.00 0.00 0.00
03:08:44 AM 24.00 0.00 2.00 1.00 7.00 0.00 0.00 0.00 0.00 …Run Code Online (Sandbox Code Playgroud) 我尝试查看/proc/sys/vm/max_map_countvm.max_map_count=16777216文件,它显示“空”,我在etc/sysctl.config中添加了一行,并想查看是否应用了更改。
我有一定的问题,需要放大它来修复应用程序中的内存崩溃,但它们仍然会发生,所以我想把这个问题划掉。