向内核或用户空间推送代码,出于性能原因?

最初我想让代码更快,最好是尝试减less内核和用户空间之间的转换 – 通过推动更多的代码在内核中运行。 不过,我已经阅读了几个像SO这样的论坛,事实正好相反,更多的代码被推入用户空间。 为什么是这样? 这似乎反直觉? 把更多的代码放入用户空间仍然需要内核用户转换,而把代码放入内核并不需要内核用户转换?

如果有人问 – 我正在考虑处理分组数据的应用程序。

编辑

所以更多的细节,我正在考虑什么时候分组数据到达 – 我想重新编写networking堆栈,并删除不适用于我的数据包处理的代码,并且零拷贝 – 将数据包数据放在用户程序可以尽可能快地访问它。

内核是一个时间敏感区域,它是您的ISR,时间节拍例程和硬件关键部分的驻留地。 正因为如此,目标是保持内核代码小而紧,进入,完成工作,然后离开。

在你的情况下,你从网络获取数据包,这是一个依赖硬件的任务(你需要从较低的网络层获取数据),所以得到你的数据,清除缓冲区,并通过DMA传输到用户空间; 然后在用户空间中进行处理。

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

如果你希望你的代码进入正式的内核版本,那么“将用户模式部分移植到内核中”通常是一个坏主意。

当然,如果你能证明这样做是最好的(主观的,我知道)的方式来实现更好的性能,成本是可以接受的(在内核的额外代码 – >更多的内核维护负担,更大内核 – >更多关于内核“太大”的抱怨等),那么一定要遵循这个路线。

但是总的来说,通过在用户模式下做更多的工作来解决这个问题可能会更好,并且如果可以的话,也可以使内核模式的任务更小。 不知道你在内核中做了什么以及你在用户模式下做什么,很难确定你应该做什么/不该做什么。 但是举例来说,将十几个“项目”加入到一个要求内核执行某些操作的块中是比调用内核十几倍更好的选择。

为了响应你的编辑描述你在做什么:传递一个用户模式的内存区域来接收数据,然后在数据包到达的时候将其复制到那里,这样做不是更好。 假设“所有的内存都是平等的”(如果不是,那么无论如何你都有“就地使用”的问题),这应该也是一样的,花在内核上的时间更少。

从用户模式到内核模式的转换需要一些时间和资源,所以只保留其中一种模式的代码可能会提高性能。

如上所述:在您的情况下,您可能最好的选择是尽可能快地获取数据,并立即在用户区域提供数据,并在用户区域进行处理…将所有处理移动到内核级别在我看来,没有必要…除非你有足够的理由这样做…没有进一步的信息,在我看来你没有理由相信你会在内核模式下比用户模式更快地做到这一点,可以省时是一种模式转换,不应该是相关的。