ゲストVMが「想定どおりに」kvm-clockドライバーを使用していない理由を本当に理解しようとしています。 RHEL 7.2、glibc-2.17、kern3.10.0を実行しています。 date
などのプログラム およびperl -e 'print time'
現在の時刻を取得しますが、システムコールを行わずに取得します。これはstraceとltraceで確認され、さらにgdbを使用して、syscall
をバイパスしたアセンブリをトレースすることで確認されます。 代わりに、rtdscp
という命令を実行しました 。
これはglibcの作成者による最適化の試みですか?これを無効にして、glibc呼び出しにシステムコールを強制的に実行させる方法はありますか(LD_PRELOADハックを除く)?
更新 2016-10-14:
最新のPOSIXドラフトを確認した後、答えの一部は明らかです。CPUにクロックを要求する方法がありますが、GNUglibcはユーザーにこの実装を誤って強制しました。回避策は、システムコールを直接呼び出すことです。 (Booooh)
_POSIX_CPUTIMEが定義されている場合、実装は、特定のプロセスのCPU時間クロックを表すclock_getcpuclockid()を呼び出すことによって取得されたクロックID値をサポートする必要があります。実装は、clock_ ()またはtimer_ のいずれかを呼び出すときの呼び出しプロセスのCPU時間クロックを表す、特別なclockid_t値CLOCK_PROCESS_CPUTIME_IDもサポートする必要があります。 ()関数。
ユーザーができることを考えると、clock_id
の概念に反対する本当の議論はありますか CLOCK_REALTIME
に設定されています 、システムコールを使用する必要がありますか?
承認された回答:
システムコールが発生していない理由は、一部のLinuxシステムコール(特に、gettimeofday(2)
などの時間に関連するもの)が原因だと思います。 およびtime(2)
)vDSOを介した特別な実装があります。これには、いくつかのsyscallのある程度最適化された実装が含まれています。
「vDSO」(仮想動的共有オブジェクト)は、カーネルがすべてのユーザー空間アプリケーションのアドレス空間に自動的にマッピングする
小さな共有ライブラリです。
カーネルが提供するシステムコールには、ユーザースペースコードが頻繁に使用されることになるものがあり、
このような呼び出しは、全体的なパフォーマンスを支配する可能性があります。これは、
呼び出しの頻度と、ユーザースペースを出て
カーネルに入る
結果として生じるコンテキストスイッチのオーバーヘッドの両方によるものです。
現在、マニュアルには、プロセスが直接アクセスできるように、必要な情報がメモリに配置されるだけであると記載されています(結局のところ、現在の時刻はそれほど秘密ではありません)。正確な実装についてはわかりません。その中でのCPUのタイムスタンプカウンターの役割についてしか推測できませんでした。
つまり、最適化を行うのは実際にはglibcではなく、カーネルです。 vdso=0
を設定することで無効にできます カーネルコマンドラインで、それをコンパイルできるはずです。ただし、glibc側で無効にできるかどうかはわかりません(少なくともライブラリにパッチを適用しないと)。
SEに関するこの質問には、他にもたくさんの情報や情報源があります。
あなたは質問で言った:
最新のPOSIXドラフトを確認した後、答えの一部は明らかです。CPUにクロックを要求する方法がありますが、GNUglibcはこの実装をユーザーに誤って強制しました。
これはかなり大胆な発言だと思います。少なくともユーザーの不利益を除いて、ユーザーに「誤って強制」したという証拠は見当たりません。 vDSOの実装は、現在のシステムで実行されているほぼすべてのLinuxプロセスで使用されています。つまり、正しく機能しなかった場合、非常に大きな苦情がすでに聞かれていたでしょう。また、受け取った時間は正しいと自分自身に言いました。
clock_gettime
からの見積もり マニュアルには、呼び出しがclock_getcpuclockid
によって返されるクロックIDをサポートする必要があると記載されているだけのようです。 、CLOCK_REALTIME
の動作については何もありません またはgettimeofday
。