命令単位の時間を計測する (準備)

命令単位の時間をはかってみましょう。この場合は、命令のクロック単位で知りたいことが多いので、CPU_CLK_UNHALTEDの値を使ってみます。
http://proc-cpuinfo.fixstars.com/2014/11/cpuclkunhalted.html
と、その前に、このCPU_CLK_UNHALTEDの値を取得する処理のオーバーヘッドも計測しておきましょう。read を使っているのでそれなりに大きな値になっている可能性があります。
https://bitbucket.org/fixstars/blog/src/76fcc97d7ab8df900b37592f852e52dbe34e1359/small_test/perf-read-overhead.c?at=master
動かしてみたところ、手元のマシンでは、平均 2000clk 程度のようです。計測対象が、200000clk(3.4GHz CPU で60usec)以上あるなら、オーバーヘッドは1%以下になるので無視して良いでしょう。
それでは以下のようにします
https://bitbucket.org/fixstars/blog/src/c25920cdac8cc69d4acd0ea2f1d493e147e398d1/small_test/inst-bench-template.c?at=master
GCC 拡張 asm を書いているので、あひーと思う人もいるかもしれませんが、今回は命令単位で計測したいので仕方ありません。
色々書いてますが、 ここ

の箇所に書かれた命令を計測しています。今回の場合は、32bit加算を計測しています。
これを動かすと、

などと出力されて、この命令が1clkで実行できることがわかります。

add をふたつ並べると、2clk になることがわかります。
さて、これで命令を計測する準備ができました…かのように見えますが、その前に、重要なことを確認しておきます。
二つ並んだ加算を次のように変更します

すると、実行結果は以下のように変化します。

eax の加算を二回実行した場合、処理時間は2clkでしたが、eax の加算と、ecx の加算を並べると、処理時間は1clkになりました。
現代のコンピュータは、さまざまな箇所が並列実行されるため、1個のデータに対して複数回処理を行う場合と、複数個のデータに対して、一回の処理を行う場合では、性能の特性が大きく変わります。
この現象は、命令単位での処理時間に限らず、メモリアクセス、マルチスレッド、HDD、プロジェクトの人員のアサイン(?)まであらゆるレイヤで見られる現象です。
次回、この違いについて、少し説明します。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です