我应该使用什么库或 API 来实现执行异步 IO 的 linux 内核模块?

What library or API should I use to implement a linux kernel module doing asynchronous IO?

首先我会告诉我的电脑环境,我的问题的背景,我的问题,然后我会解释我的确切问题。

环境:
OS: Ubuntu 16.04
内核:4.17.1
CPU:i7-6700k
内存:8GB DRAM
存储:SSD 120GB

背景:
我正在尝试针对我的特定应用程序优化 linux 内核。下面是这个应用的抽象逻辑。
1. 调用malloc,分配内存space,大小恰好是4KB(page size)
2. 将预定义数据(同样,大小为 4KB)复制到分配的内存 space.
3. 计算
4.释放分配的内存space.
这个序列大约每秒发生几千到一万次。 所以我认为每秒使用 memcpy() 数千次将预定义数据复制到分配的内存 space 是非常低效的。但是我无法修复此应用程序的代码。

我的问题:
我想通过内核模块异步执行这些副本,尽可能使用更少的 CPU 周期。因此,我正在尝试实现一个内核模块,该模块将此预定义数据异步复制到内核中的可用页面框架,并管理一个包含预定义数据的池页面框架。当我的特定应用程序请求一个页面框架时,我的内核会从这个池中给一个页面框架。

异步拷贝数据,我首先考虑的是DMA,但是我CPU的intel idma64不能异步拷贝数据内存到内存。现在,我正在尝试将此数据从辅助存储 (SSD) 复制到内存。我发现 linux.

中有名为 libaio 的异步 IO 库

我的问题:
1. 我可以在内核模块中使用 libaio 库吗?如果不是,我必须使用什么样的库或 API 才能在我的内核模块中进行异步复制?
2. libaio(或其他东西)真的会在不利用 CPU 周期的情况下进行复制吗?

我认为您不需要编写内核模块。用户 space 线程池的 CPU 固定线程与文件的内存映射集合一起工作将尽可能高效地实现。请注意 "TLB shootdown" 即避免修改进程的地址 space,并尽可能多地抛出虚拟地址 space 以避免出现问题。也许通过 madvise() 向内核提示哪些已写入的页面将永远不会再次使用,并且您应该是最佳的 - 足够多的线程将最大化 SSD 的队列深度,您希望 QD8 的目标是QD16,您应该轻松地使 NVMe link 饱和,同时将 CPU 使用率保持在 100% 以下。

如果您有许多 NVMe linked SSD,事情会变得更难,您可能需要考虑更换 Linux 具有更可扩展存储的东西 i/o,但吞吐量与那里有可伸缩性权衡。 Windows 和 FreeBSD 如果您正确地划分工作,则可以更好地扩展到很多设备,但是 Linux 将在少数设备上做得更好。祝你好运!