Linux 2.6.32.20 を実行する ARM9 ベースの組み込みボードがあります。このデバイスは、関連するキャプチャ/圧縮ハードウェアがデータを ARM メモリ内の入力 fifo に配置するビデオ カメラであり、ARM はユーザー空間からアクセスします。高レベルの制御用に、このエンコーダー用のドライバーも用意しています。
アプリケーション レベルのコード内のスレッドは、このユーザー空間の fifo をチェックし、データがある場合は、これをソケット経由で送信します。データのユーザー空間 fifo をポーリングする必要があるこのスレッドのオーバーヘッドを回避するために、ドライバーへの非常に単純な read() 呼び出しがあります。 read() 呼び出しで提供されるバッファ)。その後、この read() 呼び出しが返され、スレッドは fifo からデータが空になるまで読み取りを続行し、その後、偽の read() 呼び出しを呼び出して再び待機します。
このシステムは、フレーム ドロップが検出される前に送信できるネットワーク ストリームの数によって測定されるように、非常に効率的です。しかし、偽の read() 呼び出しを使用すると、Linux の「top」ユーティリティがアプリによる大量の CPU 使用率を報告することが判明しました。
2 つのバージョンのアプリを作成しました。1 つは上記のように動作し、もう 1 つは偽の read() を呼び出さずに代わりに usleep() 呼び出しを介在させて fifo をポーリングすることを除いて同一です。それぞれが 5 つのストリームを送信している 2 つのケースについて、「top」によって報告された CPU 使用率を見ると、次のようになります。
1) read() バージョン: CPU 12%
2) usleep() バージョン: CPU 4%
もちろん、実際のポーリングは効率が悪く、「トップ」が言っていることを無視して、フレーム ドロップが発生する前に 2 つのバージョンが同時に送信できるネットワーク ストリームの数を測定すると、上記のバージョン 1 が優先されます。
上記の read() 呼び出しが正しく動作することを確認しました。fifo にデータがなくても read() 呼び出しがすぐに返されるというバグが発生した場合、スレッドは高価な連続ポーリングを実行することになります。しかし、そうではありません。read() 呼び出しにより、スレッドは 1 秒あたり正確に 30 回実行されます。
私たちは、おもちゃのビジーボックス バージョンの "top" によって取られた近道があるのではないかと考えました。
この問題は、Linux カーネル自体が /proc//stat に示されている数値を収集する方法に何らかの制限があるに違いありません。
なぜこれが必要なのかを誰かが理解している場合は、私を正しい方向に向けてください。ありがとう!