我有一个进程使用 DMA 传输以 ~4 * 50MB/s 的速度从硬件设备读取数据,同时数据被处理、压缩并写入 4TB 内存映射文件。
每个 DMA 传输应该(并且平均而言)花费不到 20 毫秒。然而,每 5 分钟有几次 DMA 传输可能需要长达 300 毫秒的时间,这是一个大问题。
我们认为这可能与内核将脏内存映射页刷新到磁盘有关。因为如果我们停止写入映射内存,DMA 传输持续时间就很好。然而,我们很困惑这如何/为何会影响 DMA 传输以及是否有办法避免这种情况?
硬件设备有一些内存来缓冲数据,但当 DMA 传输速度如此慢时,我们就会丢失数据。
目前我们正在使用 4.1.10 lts 内核的 Arch Linux 上进行测试,但我们也尝试过 Ubuntu 14.04,但结果大多较差。硬件是 HP z820 工作站、32GB RAM 和双 Xeon E5-2637 @ 3.50Ghz (http://www8.hp.com/h20195/v2/GetPDF.aspx/c04111177.pdf)。
我们还尝试了我们软件的 Windows 版本,该版本不会遇到此特定问题,但存在许多其他问题。
答案1
Linux 有一些即时的选项,尽管它本身不是实时内核。这允许进程在准备好后立即要求将其调度在非实时进程之前,并在必要时保留 CPU。
默认情况下,进程被赋予调度策略 SCHED_OTHER。您可以将其设置为给定运行 pid 的实时 SCHED_FIFO ,或者在启动命令时chrt -f -p prio pid
为命令添加前缀。chrt -f prio
优先prio
级与普通进程无关,仅在实时进程竞争资源时使用。 ps
将这些优先级显示为负值(例如 -21 表示实时优先级 20)。
ionice --class 1 -p pid
还可以通过优先实时 io 队列来帮助调度您的进程。
答案2
答案3
我猜你还没有修改内核脏页设置。对于你的用例,我会尝试这样的事情:
/proc/sys/vm/dirty_background_bytes:50000000
/proc/sys/vm/dirty_bytes:4000000000
/proc/sys/vm/dirty_expire_centisecs:100
/proc/sys/vm/dirty_writeback_centisecs:20
(看https://www.kernel.org/doc/Documentation/sysctl/vm.txt了解详情。)
问题基本上是,如果您的系统有大量 RAM 和足够慢的存储设备,并且您正在寻求较低的最坏情况延迟,那么默认内核限制就会出现问题。实际上,系统 IO 子系统缓冲区已满,需要强制写入进程休眠,直到有足够的数据写入块设备(“刷新脏页”)。