linux -c - 尽快从用户空间通知内核,反之亦然
linux -c - notify the kernel from userspace as fast as possible and vice versa
上下文:
Debian 64 位。
制作一个 linux-only userspace networking stack 我可能会发布开源。
万事俱备,只差最后一件事。
问题:
我知道 poll
/select
/epoll
并且已经大量使用它们,但它们对我的需要来说太复杂了,而且往往会增加延迟(几纳秒 -> 太多).
需要:
一种从内核通知应用程序要处理数据包的简单方法,并使用作为多环缓冲区运行的共享 mmap
文件进行反向通知。它显然不会引起上下文切换。
我为我的 NIC 编写了一个自定义驱动程序(并计划为大联盟创建其他驱动程序 -> 1-10Gb)。
我想要两个 int
的共享数组和两个 char
的共享数组。我已经使用了多进程和非阻塞设计。
内核-> 应用程序方向的对等点(int 和char);另一个用于应用程序 -> 内核。
但是在mmap
那一刻通知的方式已经改变了。我读到 msync
可以做到,但它也很慢。那是我的问题。
互斥量导致死慢的代码。自旋锁往往会在过载时浪费 cpu 个周期。
不是在谈论繁忙的 while(1)
循环总是在读取 -> cpu 循环浪费。
你有什么推荐的?
这是我的最后一步。
谢谢
更新:
我想我将不得不支付设置中断掩码的延迟。因此,理想情况下,它应该按所需延迟期间传入数据包的数量进行分摊。我猜突发后的前几个数据包总是比较慢,因为我显然不会无限循环。
最坏的情况是数据包稀疏(因此为什么要首先寻求饱和 link 性能)。有时会遇到这种麦芽汁情况。但是谁在乎呢,无论如何它仍然比普通内核快。取舍取舍:)
看来您采用的方法在基于 RTOS 的嵌入式系统中很常见。
在 Linux 中您不应该编写自己的网络堆栈 - Linux 内核已经有一个很好的网络堆栈。您只需要实现一个 NIC 设备驱动程序(在内核中),它将所有数据包交给 Linux 网络堆栈进行处理。
任何 Linux 网络相关组件始终在内核中 - 您描述的问题提供了一些解释,说明为什么这对于合理的性能至关重要。
唯一的例外是用户空间网络过滤器(例如,用于防火墙),它们可能与 iptables
机制挂钩 - 并且会导致通过它们路由的数据包出现更高的延迟。
上下文:
Debian 64 位。
制作一个 linux-only userspace networking stack 我可能会发布开源。
万事俱备,只差最后一件事。
问题:
我知道 poll
/select
/epoll
并且已经大量使用它们,但它们对我的需要来说太复杂了,而且往往会增加延迟(几纳秒 -> 太多).
需要:
一种从内核通知应用程序要处理数据包的简单方法,并使用作为多环缓冲区运行的共享 mmap
文件进行反向通知。它显然不会引起上下文切换。
我为我的 NIC 编写了一个自定义驱动程序(并计划为大联盟创建其他驱动程序 -> 1-10Gb)。
我想要两个 int
的共享数组和两个 char
的共享数组。我已经使用了多进程和非阻塞设计。
内核-> 应用程序方向的对等点(int 和char);另一个用于应用程序 -> 内核。
但是在mmap
那一刻通知的方式已经改变了。我读到 msync
可以做到,但它也很慢。那是我的问题。
互斥量导致死慢的代码。自旋锁往往会在过载时浪费 cpu 个周期。
不是在谈论繁忙的 while(1)
循环总是在读取 -> cpu 循环浪费。
你有什么推荐的?
这是我的最后一步。
谢谢
更新:
我想我将不得不支付设置中断掩码的延迟。因此,理想情况下,它应该按所需延迟期间传入数据包的数量进行分摊。我猜突发后的前几个数据包总是比较慢,因为我显然不会无限循环。
最坏的情况是数据包稀疏(因此为什么要首先寻求饱和 link 性能)。有时会遇到这种麦芽汁情况。但是谁在乎呢,无论如何它仍然比普通内核快。取舍取舍:)
看来您采用的方法在基于 RTOS 的嵌入式系统中很常见。
在 Linux 中您不应该编写自己的网络堆栈 - Linux 内核已经有一个很好的网络堆栈。您只需要实现一个 NIC 设备驱动程序(在内核中),它将所有数据包交给 Linux 网络堆栈进行处理。
任何 Linux 网络相关组件始终在内核中 - 您描述的问题提供了一些解释,说明为什么这对于合理的性能至关重要。
唯一的例外是用户空间网络过滤器(例如,用于防火墙),它们可能与 iptables
机制挂钩 - 并且会导致通过它们路由的数据包出现更高的延迟。