
私の PC には 2 つのプロセッサがあり、それぞれが 1.86 GHz で動作することが分かっています。
私は PC プロセッサのクロック パルスを手動で測定したいと考えています。私の考えは、プログラムのアセンブラ行数とコンピュータがプログラムを実行するのに要した時間の商を計算し、CPU によって処理される時間あたりのアセンブリ命令の数を取得することです (これが「クロック サイクル」であると理解しています)。私は次のように実行しようと考えました。
- C プログラムを作成し、それをアセンブリ コードに変換します。
- 私は以下を実行します。
$gcc -S my_program.c
これは、最後のステップである my_program.c をバイナリ オブジェクトに変換することを除く、コンパイル プロセス全体を実行するように gcc コンパイラに指示します。こうして、アセンブラ コードに変換された C プログラムのソースを含む my_program.s というファイルが作成されます。 プログラムの行数を数えます (この数を N とします)。次のようにする
$ nl -l my_program.s | tail -n 1
と、次の結果が得られました。1000015 .section .note.GNU-stack,"",@progbits
つまり、プログラムには 100 万行のコードが含まれているということです。
- そうします。
$gcc my_program.c
実行できるようにするためです。 $time ./a.out
プログラムの実行に費やされた時間 (T と呼びます) を取得するには、次のようにします(「a.out」は my_program.c のバイナリ オブジェクトの名前です)。次のようにすると、次の結果が得られます。real 0m0.059s user 0m0.000s sys 0m0.004s
私が探している時間 T は、リストに表示されている最初の時間、つまり「実際の時間」であると考えられます。他の時間は、私が実行したのと同じ瞬間にシステム内で実行されている他のリソースを参照しているからです./a.out
。
つまり、N = 1000015 行、T = 0.059 秒です。N/T 除算を実行すると、周波数は 17 MHz に近くなりますが、これは明らかに正しくありません。
次に、コンピューター上で他のプログラムが実行されていてハードウェア リソースを消費している (オペレーティング システム自体ではなく) ため、プロセッサが「処理能力」を「分割」し、クロック パルスが遅くなるのではないかと考えましたが、確信はありません。
しかし、これが正しいとすれば、プログラムが消費する CPU リソース (またはメモリ) の割合も調べる必要があると考えました。そうすれば、実際の CPU 速度について (十分に) 近似した結果を実際に得ることができるからです。
そして、これはプログラムの「リソース消費値」をどうやって調べるかという問題につながります。コマンドについて考えました$ top
が、プログラムの実行時間が短い (0.059 秒) ため、すぐに破棄されました。この短い時間内にメモリ使用量のピークを一目で区別することはできません。
それで、これについてどう思いますか? あるいは、私に何を勧めますか? 私がやろうとしているこの作業を実行するプログラムがあることは知っていますが、できるだけ「普遍的な方法」で実行することに興味があるので (より信頼性が高いように思われる)、生の bash を使用して実行することを好みます。
答え1
それはうまくいきません。各命令の実行にかかるクロック サイクル数 (1 つだけではなく、かなりの数かかります) は、その命令を取り巻く命令の正確な組み合わせに大きく依存し、CPU モデルによって異なります。また、割り込みが発生し、カーネルやその他のタスクが、自分の命令と混ざって命令を実行します。さらに、周波数は負荷と温度に応じて動的に変化します。
最近の CPU には、正確なクロック サイクル数をカウントするモデル固有のレジスタがあります。これを読み取り、高解像度のタイマーを使用して一定期間後に再度読み取り、2 つを比較して、その期間の (平均) 周波数を調べることができます。