文章目录
- 参考
- 快慢路径解释
- 需要优化快路径,而慢路径不需要(概率问题)
- 实例
- straight-line code path
- 跳转
参考
https://kernelnewbies.org/FAQ/FastpathAndSlowpath https://www.eecis.udel.edu/~cavazos/nips-sl2-final.pdf /Documentation/static-keys.txt
快慢路径解释
快与慢的区别主要体现在代码量上。如果没有竞争,直接占有,非常快。如果资源被占用,需要一些列的强制等待操作,非常慢。 In general, “fast path” is the commonly run code that should finish very quickly. For example, when it comes to spinlocks the fast path is that nobody is holding the spinlock and the CPU that wants it can just take it.
Conversely, the slow path for spinlocks is that the lock is already taken by somebody else and the CPU will have to wait for the lock to be freed.
需要优化快路径,而慢路径不需要(概率问题)
The first case is the common one that should be optimized. The second one is not as important and does not need to be optimized much at all.
In this example, the reason for not optimizing the spinlock code for dealing with lock contention is that locks should not be contended. If they are, we need to redesign the data structures or the code to avoid contention in the first place! 要优化慢路径,不如直接优化,自由锁定。 You will see similar tradeoffs in the page locking code, the scheduler code (common cases are fast, unlikely things are put out of line by the compiler and are “behind a jump”) and many other places in the kernel.
实例
Documentation/static-keys.txt 静态键值的作用在性能敏感的快速路径核心代码中很少使用。ftrace/tracepoints等功能。 Static keys allows the inclusion of seldom used features in performance-sensitive fast-path kernel code, via a GCC feature and a code patching technique. A quick example::
straight-line code path
在这个文档Documentation/static-keys.txt里还有提到straight-line,这也是一个新名词。这种直线代码路径意味着在这一小段汇编代码中没有跳转指令。 下面这句话的意思是说,产生的汇编代码,不会造成“直线”的性质发生改变,只是在直线代码路径上添加no-op五字节的空指令。当需要此功能时,使用它jump替换此指令no-op指令。完成非直线代码执行。虽然改变分支的走向代价比较大,但是分支选择非常自由,怎么填都可以。这种方法也是性能的权衡。 Thus, by default the ‘printk’ will not be emitted. And the code generated will consist of a single atomic ‘no-op’ instruction (5 bytes on x86), in the straight-line code path. When the branch is ‘flipped’, we will patch the ‘no-op’ in the straight-line code path with a ‘jump’ instruction to the out-of-line true branch. Thus, changing branch direction is expensive but branch selection is basically ‘free’. That is the basic tradeoff of this optimization.
跳转
跳转带来的性能问题:频繁cache切换,如果straight-line代码,带来的cache切换会少。
Currently, tracepoints are implemented using a conditional branch. The conditional check requires checking a global variable for each tracepoint. Although the overhead of this check is small, it increases when the memory cache comes under pressure (memory cache lines for these global variables may be shared with other memory accesses). As we increase the number of tracepoints in the kernel this overhead may become more of an issue. In addition, tracepoints are often dormant (disabled) and provide no direct kernel functionality. Thus, it is highly desirable to reduce their impact as much as possible. Although tracepoints are the original motivation for this work, other kernel code paths should be able to make use of the static keys facility.