34

あるスレッドからネットワーク パケットを送信し、別の CPU コアで実行される 2 番目のスレッドで応答を受信して​​います。私のプロセスは、各パケットの送信と受信の間の時間を測定します (ping と同様)。rdtsc を使用して、実装に必要な高解像度、低オーバーヘッドのタイミングを取得しています。

すべての測定値は信頼できるように見えます。それでも、tsc がコア間で同期されていないことを示唆するテキストを読んでいるので、コア間の rdtsc の精度が心配です。

ウィキペディアでTSCに関する次の情報を見つけました

一定の TSC 動作により、各クロック ティックの持続時間が一定になり、プロセッサ コアの周波数が変化した場合でも TSC をウォール クロック タイマーとして使用できるようになります。これは、すべての Intel プロセッサで前進するアーキテクチャ上の動作です。

それでもコア全体の精度が心配です。これが私の質問です

より詳しい情報

  • Intel nehalem マシンでプロセスを実行しています。
  • オペレーティング システムは Linux です。
  • すべてのコアに対して「constant_tsc 」CPU フラグが設定されます。
4

6 に答える 6

31

X86_FEATURE_CONSTANT_TSC+ X86_FEATURE_NONSTOP_TSCcpuid のビット (edx=x80000007、ビット #8;詳細については、Linux カーネルの機能を確認してください) unsynchronized_tsc

IntelのDesignerのvol3b、セクション16.11.1 Invariant TSCには、次のように書かれています

"16.11.1 インバリアント TSC

新しいプロセッサのタイム スタンプ カウンターは、インバリアント TSC と呼ばれる拡張機能をサポートしている場合があります。インバリアント TSC に対するプロセッサのサポートは、CPUID.80000007H:EDX[8] で示されます。

不変の TSC は、すべての ACPI P-、C- で一定の​​速度で実行されます。および T ステート。これは、前進するアーキテクチャの動作です。不変の TSC をサポートするプロセッサでは、OS はウォール クロック タイマー サービスに (ACPI または HPET タイマーの代わりに) TSC を使用する場合があります。TSC 読み取りははるかに効率的であり、リング遷移やプラットフォーム リソースへのアクセスに関連するオーバーヘッドが発生しません。」

したがって、TSC をウォールクロックに使用できる場合、それらは同期していることが保証されます。

于 2010-11-10T13:52:37.817 に答える
3

最近のプロセッサでは、同じパッケージの個別のコア間 (つまり、コア iX プロセッサが 1 つだけのシステム) で実行できますが、rtc を共有しないため、個別のパッケージ (プロセッサ) では実行できません。CPU アフィニティ (関連するスレッドを特定のコアにロックする) を介して回避できますが、アプリケーションの動作方法によって異なります。

Linux では、プロセッサがパッケージ全体に対して有効な単一の tsc を持っているかどうかを確認するために、/proc/cpuinfo の constant_tsc をチェックできます。raw レジスタは CPUID.80000007H:EDX[8] にあります。

私が読んだものの、プログラムでまだ確認していないのは、リビジョン 11h 以降の AMD CPU は、この cpuid ビットに対して同じ意味を持つということです。

于 2014-01-17T12:52:57.897 に答える
3

実際、コアは TSC を共有していないようです。このスレッドを確認してください: http://software.intel.com/en-us/forums/topic/388964

要約すると、異なるコアは TSC を共有しません。コアが特定のエネルギー状態に変化すると、TSC が同期しなくなることがありますが、これは CPU の種類に依存するため、Intel のドキュメントを確認する必要があります。ほとんどのオペレーティング システムは、起動時に TSC を同期しているようです。
コア i5 プロセッサを搭載した Linux Debian マシンで、エキサイティングな反応アルゴリズムを使用して、さまざまなコアの TSC の違いを確認しました。エキサイター プロセス (1 つのコア内) は TSC を共有変数に書き込み、反応するプロセスがその変数の変化を検出すると、その値を比較し、それを自身の TSC と比較します。これは、私のテスト プログラムの出力例です。

TSC ping-pong test result:
TSC cores (exciter-reactor): 0-1
100 records, avrg: 159, range: 105-269
Dispersion: 13
TSC ping-pong test result:
TSC cores (exciter-reactor): 1-0
100 records, avrg: 167, range: 125-410
Dispersion: 13

エキサイター CPU が 0 の場合 (平均 159 ティック) の反応時間は、エキサイター CPU が 1 の場合 (167 ティック) とほぼ同じです。これは、それらがかなりよく同期されていることを示しています (おそらく、いくつかの目盛りの違いがあります)。他のコアペアでも、結果は非常に似ていました。
一方、rdtscp アセンブリ命令は、TSC を読み込んだ CPU を示す値を返します。あなたのケースではありませんが、単純なコード セグメントで時間を測定したい場合や、コードの途中でプロセスが CPU から移動していないことを確認したい場合に役立ちます。

于 2014-02-19T22:03:19.940 に答える
2

Linux では、CLOCK_MONOTONIC_RAW で clock_gettime(3) を使用できます。これにより、ナノ秒単位の結果が得られ、ntp 更新の影響を受けません (発生した場合)。

于 2010-08-29T08:40:02.280 に答える
1

rdtsc を使用しないことをお勧めします。移植性がないだけでなく、信頼性が低く、一般的には機能しません。一部のシステムでは、rdtsc が均一に更新されません (speedstep を使用している場合など)。正確なタイミング情報が必要な場合は、ソケットに SO_TIMESTAMP オプションを設定し、recvmsg() を使用して (マイクロ秒の分解能) タイムスタンプでメッセージを取得する必要があります。

さらに、SO_TIMESTAMP で取得したタイムスタンプは、実際にはカーネルがパケットを取得した時間であり、タスクがたまたま気付いた時間ではありません。

于 2010-08-02T21:50:46.547 に答える
1

sched_set_affinity()1 つの CPU コアでスレッドを実行するために、APIを使用してスレッド アフィニティを設定できます。

于 2010-10-16T23:27:48.133 に答える