linuxカーネルのlikelyとunlikely

1607 ワード

前言
カーネルバージョン:linux 4.13 linuxカーネルでは、if(likely(x))またはif(unlikely(x))文がよく見られますが、likelyとunlikelyはどういう意味ですか.本稿ではlikelyとunlikelyについていくつかの議論を行う.
likelyとunlikely
参考/include/linux/compiler.h */
# define likely(x)  __builtin_expect(!!(x), 1)
# define unlikely(x)    __builtin_expect(!!(x), 0)

上記ソースコードには組み込み関数が採用されています_builtin_expectは、built in functionという定義を行います.  __builtin_expectの関数プロトタイプはlong_builtin_expect(long exp,long c)は、完全な式expの値を返します.その役割は、式expの値がcに等しいことを期待することです(exp==c条件が成立する機会がほとんどの場合、パフォーマンスが向上します.そうしないと、パフォーマンスが低下します).注意、_builtin_expect(lexp,c)の戻り値はexp値そのものであり、expの値は変更されません.  __builtin_expect関数はgccを条件分岐予測に導くために用いられる.1つの命令を実行する場合、流水ラインの作用により、CPUは次の命令の指取りを同時に完了することができ、これによりCPUの利用率を向上させることができる.条件分岐命令を実行する場合、CPUは次の実行をプリフェッチするが、条件分岐の結果が他の命令にジャンプした場合、CPUがプリフェッチした次の命令は役に立たず、流水ラインの効率が低下する.また、ジャンプ命令は、順次実行される命令に対してCPU時間を多く消費し、できるだけジャンプを実行しないようにすれば、CPU性能を向上させることができる.if(likely)==if(value),if(unlikely)==if(value)を表面から簡単に見ることができます.つまりlikelyとunlikelyは同じですが、実際には実行が異なり、likelyを加えるとvalueの値が本物である可能性が高いという意味で、ifを実行する機会が大きく、unlikelyはvalueの値が偽物である可能性が高く、elseを実行する機会が大きいという意味です.このような修飾を加えて、バイナリコードにコンパイルするときlikelyはifの後の実行文を前のプログラムに追従させ、unlikelyはelseの後の文を前のプログラムに追従させ、cacheにプリフェッチされ、プログラムの実行速度を増加させる.では、上記の定義でなぜ使うのか!!記号は?コンピュータのboolロジックは0と1だけで、0でないのは1で、likely(x)のパラメータが論理値でない場合、使用することができます!!シンボルは論理値1または0に変換されます.例えば:!!(3)=!(!(3))=!0=1となると,パラメータ3を論理1に変換する.簡単に理解すると、likely(x)はxが論理真(1)である可能性が高い.unlikely(x)はxが論理的偽(0)である可能性が高いことを表す.