mmap 和慢速 DMA 传输

mmap 和慢速 DMA 传输

我有一个进程使用 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

您的设备是否连续运行几分钟,或者传输过程中是否有定期暂停?

如果有暂停,您可以强制内核空缓冲区和缓存在此期间,因此此活动不会干扰 DMA 传输。或者,您可以将内核配置为BDFLUSHR1 秒的间隔,以便内核每次决定刷新缓冲区时要写入的数据更少。

如果您需要确保连续运行,您将需要具有更多通道的 RAM,以便 CPU 和您的设备可以同时访问内存(事实证明,您已经有一个 4 通道内存控制器)。确保您的 RAM 配置为非联动模式,如果此选项可用。确保您在内存通道对应的 4 个插槽中安装了类似的 DRAM 模块,以便您的内存控制器实际上可以在 4 通道模式下运行。

答案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 子系统缓冲区已满,需要强制写入进程休眠,直到有足够的数据写入块设备(“刷新脏页”)。

相关内容