カーネル同期の章を読んUnderstanding the Linux kernel (Bovet & Cesati),
でいると、スピンロック取得コードは次のように要約されます。
1: lock:
btsl $0, slp
jnc 3
2: testb $1, slp
jne 2
jmp 1
3:
今、私は当初、ネストされたループを持つことは無駄に思え、次のようなものを実装できると考えていました。
1: lock:
btsl $0, slp
jc 1
これははるかに簡単です。lock
ただし、他のCPUに影響を与え、単純なCPUよりもタイミングbtsl
が大きいため、なぜそれを行ったのかがわかりtestb
ます。
頭を動かすことができなかったのは、その後のスピンロックのリリースです。この本は、それが次のことをもたらすと述べています:
lock:
btrl $0, slp
私の質問は基本的になぜですか?lock/mov-immediate
コンボの方が速いようです。
カーネルにはバグがないという規則に従って(カーネル内の他の多くの場所で想定されている)、古い状態は1になるため、古い状態をキャリーフラグにする必要はありません(そうはなりません)。まだ取得していない場合は、リリースしようとしています)。
そして、少なくとも386では、mov
aはaよりもはるかに高速です。btrl
だから私は何が欠けていますか?
後のチップでそれらの命令のタイミングを変更しましたか?
本が印刷されてからカーネルは更新されましたか?
その本はまったく間違っている(または簡単な説明を示している)のですか?
より高速な命令では満たされないCPU間の同期に関する他の側面を見逃したことがありますか?