用户空间Vs内核空间程序性能差异

时间:2012-06-30 07:55:17

标签: performance caching kernel cache-control

我有一个顺序用户空间程序(某种内存密集型搜索数据结构)。以CPU周期数量来衡量的程序性能取决于底层数据结构的内存布局和数据高速缓存大小(LLC)。

到目前为止,我的用户空间程序已经调整为死亡,现在我想知道是否可以通过将用户空间代码移动到内核(作为内核模块)来获得性能提升。我可以想到以下因素可以改善内核空间的性能......

  1. 无系统调用开销(每次系统调用获得多少CPU周期)。这不太重要,因为我在我的程序中几乎不使用任何系统调用,除了在程序启动时分配内存。
  2. 控制调度,我可以创建一个内核线程,使其在给定的核心上运行而不会被丢弃。
  3. 我可以使用kmalloc内存分配,因此可以更好地控制分配的内存,也可以通过控制分配的内存来更精确地控制缓存着色。值得一试吗?
  4. 我向内核专家提出的问题......

    • 我是否错过了上述列表中可以进一步提高性能的任何因素?
    • 是否值得尝试,或者直截了当地知道我的性能不会提高很多?
    • 如果在内核中可以获得性能增益,那么估计可以获得多少增益(任何理论猜测)?

    感谢。

2 个答案:

答案 0 :(得分:6)

关于第1点:内核线程仍然可以被抢占,所以除非你进行大量的系统调用(你不是这样),否则这对你来说不会太多。

关于第2点:您可以通过在Linux上使用sched_setaffinity()设置其关联来将线程固定到特定核心。

关于第3点:您期待什么额外控制?您已经可以使用mmap()从用户空间分配页面对齐的内存。这已经允许您控制缓存的集合关联性,并且您可以使用内联汇编或编译器内在函数来进行任何手动预取提示或非时间写入。内核和用户空间中分配的内存之间的主要区别在于kmalloc()分配有线(不可分页)内存。我不明白这会有什么帮助。

我怀疑在使用SIMD,多线程或进行进一步算法或内存优化的并行化方面,您会看到更好的ROI。

答案 1 :(得分:5)

为您的程序创建一个专用的cpuset,并将所有其他进程移出它。然后使用以下内容将您的进程优先级置于FIFO调度策略的实时状态:

struct sched_param schedparams;
// Be portable - don't just set priority to 99 :)
schedparams.sched_priority = sched_get_priority_max(SCHED_FIFO);
sched_setscheduler(0, SCHED_FIFO, &schedparams);

不要在单核系统上这样做!

使用alloca(3)保留足够大的堆栈空间并触摸所有已分配的堆栈内存,映射足够的堆空间,然后使用mlock(2)mlockall(2)来固定处理内存。

即使您的程序是顺序程序,如果在多插槽Nehalem或后Nehalem Intel系统或AMD64系统上运行,NUMA效果可能会降低程序速度。使用numa(3)中的API函数来分配和保留内存,使其尽可能靠近程序执行的NUMA节点。

尝试其他编译器 - 其中一些编译器可能优于您当前使用的编译器。例如,英特尔的编译器在布置指令时非常具有攻击性,可以从乱序执行,流水线操作和分支预测中受益。