私はpercpuの統計値として、Linuxカーネル内の接続数の半分をsigned int型の変数を選んだ、私はグローバル変数の選択の余地原子の種類を持っていないが、私はunsigned int型の一般的なグローバル変数を保護するためにスピンロックを使用していませんでした。
signed int型は、異なるCPU接続の間のアカウントの移行プロセスに取るためpercpu変数を選択しました。
これまでのところ、すべてが完璧percpu変数、軽量かつノーロック操作は、統計カウンタとしての最大の利点です。私たちが読んでいる統計カウンタとして、我々は、一般的に読み取るためにロックフリーな方法を使用するので、ある程度の誤差を許容することです。
for_each_possible_cpu(i) {
res += per_cpu_ptr(ptr, i);
}
私たちは、上記のステートメントの実装がどのように高速トラバースすべてに関係なく、CPUの時間を要していないことを知っているが、それは、時間がかかり、この期間中、percpu変数は累積的変動のロジックが発生する可能性があり、実行中に取得することができませんトラバース。
幸いなことに、これらの統計を読むことを与えている、と男の目的はいくつかのルールによって導出値にこれらの統計情報を読み取ることで、通常はデータの解像度がミリ秒以下になっていませんが必要です。
しかし、カーネルが行う方法を、これらの値を必要とする場合は?
そのようなこれらの変数の値に応じてデータ・オブジェクトを実行するコアロジックを解放するかどうかなど。
for_each_possible_cpu(i) {
res += per_cpu_ptr(ptr, i);
}
if (res == 0)
free_something(...);
上記のコードはどのように行う、その後、⚠️明らかに危険なのですか?
非常に単純な、読み書きロックをすることができます。しかし、通常、読み書きをロックし、ちょうど反対の使用:
- percpu変数を更新する際に、読み取りロックしてください。
- percpu変数を読み込む際に、書き込みロックしてください。
次のように更新ロジックは次のとおりです。
signed int *per_cpu_counter = per_cpu_ptr(..., this_cpu);
...
read_lock(&percpu_wrlock);
*per_cpu_counter ++;
read_unlock(&percpu_wrlock);
次のように読むロジックは次のとおりです。
write_lock(&percpu_wrlock);
for_each_possible_cpu(i) {
res += per_cpu_ptr(ptr, i);
}
if (res == 0)
free_something(...);
write_unlock(&percpu_wrlock);
読み取り/書き込みロック中は無効、けれどもつかむ、およびバリアを挿入しますが、Linuxカーネルや特定のプラットフォームの特定のアーキテクチャに特有の、これらは一見ますパフォーマンスに影響を及ぼす、と言う、オペレーティングほとんど無視できるのをサーバのほとんどは、カーネルをコンパイルするためにカーネルプリエンプションオプションを閉じています。
ビューのではなく、一般からのポイントは、すべてのプロセスを通じて詳細情報を、引き、CPUのpercpu変数の蓄積を削除する場合は、これは少なくとも、非常に高速であります 操作、言及し、マシンのCPUのほとんどは、基本的に3桁以下のオーダーであるので、これではありません 一定の値自体が非常に小さいことです。
管理者は、トリックを参照するのを待つない、でもあまりにも20のために、トラバースにマネージャを参照するのを待つことはありません。
2007年の夏には、管理者は関係なく、DNSの最初の遅い、マネージャと述べ、作業者は、北京で部屋を取ったIPは、コードを書くサーバーで死亡しました。その後、このサーバーの再配置は、労働者は、私に物事を残して、私はこれがハードコードされたが、私は、設定ファイルではなく、コードのマクロを使用することを好むが、私は非常に多く、このアプローチに同意します...
私は、設定ファイルに書いたと20個の一般的に使用されるIPアドレスを死ぬ、最初の10は、IPサーバです、10は私の好み10 DNSで、その後、最後の行に、効果は本当に良いです!
しかし、コードを見てマネージャーは、マネージャーが20 IPのため、管理者は、このサイクルは時間がかかり言った、のために、管理者は、私はこのように見えるためにそれを変更して、私は、私の百Nanbianを変更させる必要がありました:
if (是IP1)
...
else if (是IP2)
...
else if (是IP3)
...
else if (是IP4)
...
else if (是IP5)
...
else if (是IP6)
...
...
else if (是IP20)
...
else
...
OK、循環を排除し、誰もが仕事オフ歌い、コードの量を増やします。
温州の靴は、雨水が脂肪ではありません、濡れました。