2

最初我认为要使代码更快,最好尝试减少内核和用户空间之间的转换——通过推动更多代码在内核中运行。然而,我在一些类似 SO 的论坛上读到,实际上相反的情况已经完成——更多的代码被推送到用户空间。为什么是这样?这似乎违反直觉?将更多代码放入用户空间仍然需要内核-用户转换,而将代码放入内核并不需要内核-用户转换?

万一有人问-我正在考虑处理数据包数据的应用程序。

编辑

所以更多细节,我正在考虑数据包数据何时到达 - 我想重写网络堆栈并删除不适用于我的数据包处理并且零复制的代码 - 将数据包数据放在用户程序可以的地方尽快访问它。

4

3 回答 3

4

内核是一个时间敏感区域,它是您的 ISR、时间滴答例程和硬件关键部分所在的位置。因此,目标是保持内核代码小而紧凑,进入,完成工作,然后退出。

在您的情况下,您从网络获取数据包,这是一项依赖于硬件的任务(您需要从较低的网络层获取数据),因此获取数据,清除缓冲区,然后通过 DMA 传输将其发送到用户空间;然后在用户空间中进行处理。

根据我的经验:在内核中执行代码所获得性能不会超过在内核中执行更多代码所损失的整体性能。

于 2013-04-08T15:24:08.893 回答
1

从用户模式到内核模式的转换需要一些时间和资源,因此仅将代码保持在其中一种模式可能会提高性能。

如前所述:在您的情况下,您最好的选择可能是尽可能快地获取数据并立即使其在用户区可用并在用户区进行处理......将所有处理移至内核级在我看来没有必要......除非你有充分的理由这样做......没有更多信息在我看来你没有理由相信你会在内核模式下比用户模式更快地做到这一点,所有你可以不时进行模式转换,这不应该是相关的。

于 2013-04-08T15:19:24.487 回答
1

如果您希望您的代码进入官方内核版本,那么“将其用户模式部分改组到内核中”通常可能是个坏主意。

当然,如果您能证明这样做是获得更好性能的最佳(主观,我知道)方式,并且成本是可以接受的(就内核中的额外代码而言 -> 内核的维护负担更大,更大kernel -> 更多关于内核“太大”等的抱怨),然后一定要遵循这条路线。

但总的来说,最好通过在用户模式下做更多的工作来解决这个问题,并使内核模式任务更小,如果这完全可以替代的话。如果不确切知道您在内核中正在做什么以及您在用户模式下正在做什么,很难确定您应该/不应该做什么。但是,例如,将十几个“项目”分批成一个块,即一个请求内核做某事是比调用内核十几次更好的选择。

作为对描述您正在做什么的编辑的回应:传递用户模式内存区域以接收数据,然后在数据包到达时复制到该区域不是更好吗?假设“所有内存都是平等的”[如果不是,那么无论如何你都会遇到“就地使用”的问题],这应该同样有效,在内核中花费的时间更少。

于 2013-04-08T15:22:26.300 回答