1

ライブラリのいくつかの関数のレイテンシをテストしています。そうするために、入口と出口で rdtsc() を使用します。結果の rdtsc 値、実行中の最小値、最大値、および呼び出し回数 (平均を取得するため) を追跡します。出力のグラフを見ると、平均で約 100 サイクルほどですが、約 20000 サイクルのスパイク、またはそのような不穏なものがあります (これは、関数の 3 つまたは 4 つの分岐の単純な分岐予測ミスよりもはるかに悪いようです)。 )。cachegrind を実行したところ、次のような出力が得られました。

==14038==
==14038== I   refs:      2,260,149,383
==14038== I1  misses:           10,408
==14038== LLi misses:            3,978
==14038== I1  miss rate:          0.00%
==14038== LLi miss rate:          0.00%
==14038==
==14038== D   refs:      1,100,962,403  (773,471,444 rd   + 327,490,959 wr)
==14038== D1  misses:           26,419  (     13,447 rd   +      12,972 wr)
==14038== LLd misses:           15,446  (      5,701 rd   +       9,745 wr)
==14038== D1  miss rate:           0.0% (        0.0%     +         0.0%  )
==14038== LLd miss rate:           0.0% (        0.0%     +         0.0%  )
==14038==
==14038== LL refs:              36,827  (     23,855 rd   +      12,972 wr)
==14038== LL misses:            19,424  (      9,679 rd   +       9,745 wr)
==14038== LL miss rate:            0.0% (        0.0%     +         0.0%  )
==14038==
==14038== Branches:        327,248,773  (297,539,058 cond +  29,709,715 ind)
==14038== Mispredicts:         980,262  (    978,639 cond +       1,623 ind)
==14038== Mispred rate:            0.2% (        0.3%     +         0.0%   )

予測ミスと分岐ミス率が非常に低いため、何が起こっているのか疑問に思います.20Kサイクルのオーダーでこのような高いレイテンシ測定値が頻繁に見られるのはなぜですか? この謎を解くために、他に調べられることは何ですか? どうなり得るか?

実際、気が遠くなるようなことは、rdtsc 測定値の 1 つが単に次のようなものをラップしていることです。

if(memberVarBool_)
{
    memberVarPtr->smallFuncWithThreeIntAssignsAndstdmax;
}

そして、この男は私に多くの「25」サイクルのものを見せてくれます。

更新: gettimeofday を使用して、rdtsc に固有の問題を回避し、同じものが表示されることを期待して、ナノ秒単位でレイテンシーを測定するように切り替えました...測定でプリエンプションと外部またはプロセスの影響を回避できる方法はありますか?

4

2 に答える 2

1

オペレーティング システムが rdtsc() への 2 つの呼び出しの間に別のタスク/プロセスをスケジュールしないようにするにはどうすればよいですか? rdtsc() への 2 つの呼び出しの間にハードウェア割り込みが発生しないようにするにはどうすればよいですか?

どちらの場合も、2 つの読み取り値の差にスパイクのように見えるものを引き起こします。

于 2012-07-20T20:34:59.900 に答える
0

生のサンプルを保持する場合は、それらをグラフ化して外れ値を無視するか、平均/平均ではなく中央値を取ることができます。ところで、プリエンプションと同様に、rdtsc が間隔を誤って報告する可能性があるもう 1 つの理由は、スレッドがコアを移動することです。各コアには独自の TSC レジスタがあり、多くのボックスでは、どの時点でも同じ値に同期されません。プロセスを特定のコアに固定すると役立ちます。ハードウェア割り込みを無効にするには、おそらく root になる必要がありますが、ユーザー プロセス コンテキストでそれがどのように行われるかはわかりません。

これとは別に、何かが名目上ナノ秒を返すからといって、実際にはそうするとは限りません。そのような関数の多くは、より遅いティックのドライバーを使用して数千万ナノ秒単位でジャンプします。関数を繰り返し呼び出すと、再びジャンプするまで同じ値が返されます。

于 2012-07-20T22:30:21.873 に答える