Cortex-A72で-O3ではなく-O0を使用した単純なタイトループのサイクルでこの高い変動が発生する原因は何ですか?
コードの一部に対して非常に一貫性のあるランタイムを取得するためにいくつかの実験を行っています。私が現在計時しているコードは、かなり恣意的なCPUバウンドのワークロードです。 int cpu_workload_external_O3(){ int x = 0; for(int ind = 0; ind < 12349560; ind++){ x = ((x ^ 0x123) + x * 3) % 123456; } return x; } 割り込みを無効にし、上記の関数の10回の試行を実行するカーネルモジュールを作成しました。各試行のタイミングは、前後のクロックサイクルカウンターの差をとることによって計っています。その他の注意事項: マシンはARM Cortex-A72であり、それぞれ4コアの4ソケット(それぞれに独自のL1キャッシュがある) クロック周波数スケーリングはオフです ハイパースレッディングはサポートされていません マシンは、一部の最低限のシステムプロセスを除いて、実質的に何も実行していません 言い換えると、システム変動のほとんど/すべての原因が説明されていると私は信じています。特に、割り込みを無効にしてカーネルモジュールとして実行した場合spin_lock_irqsave()、コードは実行間でほぼ同じパフォーマンスを達成するはずです(たぶん小さなパフォーマンスヒット)最初の実行では、いくつかの命令が最初にキャッシュにプルされますが、それだけです)。 実際、ベンチマークされたコードがでコンパイルされた場合、-O3平均で〜135,845,192のうち最大で200サイクルの範囲があり、ほとんどの試行でまったく同じ時間がかかりました。ただし、を使用してコンパイルする-O0と、範囲は262,710,916のうち158,386サイクルまで増加します。範囲とは、最長実行時間と最短実行時間の差を意味します。さらに、-O0コードでは、どの試行が最も遅い/最も速いかについて一貫性があまりありません-直感的には、ある場合には、最も速いものが最初であり、最も遅いものが直後のものでした! それで、-O0コードの変動性のこの高い上限を引き起こしている可能性があるものは何ですか?アセンブリを見ると、-O3コードはすべて(?)をレジスタに格納しているようですが、-O0コードにはたくさんの参照spがあるため、メモリにアクセスしているようです。しかし、それでも、すべてがL1キャッシュに取り込まれ、かなり確定的なアクセス時間でそこに座っていることが期待されます。 コード ベンチマーク対象のコードは上記のスニペットにあります。組み立ては下にあります。とgcc 7.4.0以外はフラグなしでコンパイルされました。-O0-O3 -O0 0000000000000000 <cpu_workload_external_O0>: 0: d10043ff sub sp, sp, …