ライブラリのいくつかの関数のレイテンシをテストしています。そうするために、入口と出口で 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 に固有の問題を回避し、同じものが表示されることを期待して、ナノ秒単位でレイテンシーを測定するように切り替えました...測定でプリエンプションと外部またはプロセスの影響を回避できる方法はありますか?