synprog のパフォーマンスデータを収集し、test.1.er を開いたことを確認してください。 これらの作業がまだ済んでいない場合には、synprog サンプルのデータ収集を参照して実行してください。
ここでは、cputime() と icputime() の 2 つの関数のユーザー CPU 時間について検証します。 どちらの関数にも、変数 x を 1 ずつ増分する for ループが含まれています。 cputime() における x は浮動小数点ですが、 icputime() における x は整数です
表示をスクロールする代わりに「検索」ツールで関数を見つけることができます。
2 つの関数の排他的ユーザー CPU 時間を比較します。 icputime() よりはるかに多くの時間が cputime() で消費されます。
同じデータを示す新しいアナライザウィンドウが表示されます。 両方のウィンドウが見えるようにウィンドウを調整します。
注釈付きソースリストにより、どのコード行が CPU 時間を費やしているかが分かります。 いずれの関数の場合も、ほとんどの時間はループ行と x が増分される行で消費されています。
icputime() のループ行で費やされる時間は cputime() のループ行で費やされる時間とほぼ同じですが、x が増分される行に要する時間は、icputime() の方が cputime() よりはるかに少ないことが分かります。
「検索」ツールのコンボボックスで「高メトリック値」を選択して検索することによっても、これらの命令を見つけることができます。
cputime() では、fstod と fdtos の命令の実行に長時間が費やされます。 これらの命令は x の値を単精度浮動小数点値から倍精度浮動小数点値に変換し、再び逆方向に変換します。 この処理を行うことにより、倍精度浮動小数点定数である 1.0 ずつ x をインクリメントできるのです。
icputime() で行われる操作は読み込み、加算、格納だけであり、これらに要する時間は cputime() での対応する命令にかかる時間のほぼ 3 分の 1 にすぎません。その理由は、変換が不要だからです。 値 1 をレジスタにロードする必要もありません。値 1 は、1 つの命令によって直接 x に加算できます。
synprog のソースコードを編集し、cputime() の x を double に変更します。 synprog のデータ収集に使用した以下のコマンドを端末ウィンドウに入力し、プログラムを再コンパイルして新しい実験を記録します。
% make % collect synprog
新しい実験 test.3.er をパフォーマンスアナライザで開きます。
x が変化すると、時間に対してどのような影響がありますか? 注釈付き逆アセンブリリストにどのような違いが現れましたか?
関連項目 | |
---|---|
「関数」タブ 「ソース」タブ 「逆アセンブリ」タブ |